专业的JAVA编程教程与资源

网站首页 > java教程 正文

JAVA多线程小游戏(java多线程实战项目)

temp10 2024-09-10 21:09:22 java教程 15 ℃ 0 评论

今天介绍一下我用多线程写JAVA 程序时需要注意的地方:

首先给大家看一下效果图:(大家也可以找一个其他的背景图)黑球是我可以用鼠标控制的,其他小球则是随机产生,当我的小球和随机小球球心距离小于半径时便可以将随机小球消灭,同时控制随机小球数量不超过5个。线程包括:产生随机小球的线程inThread、显示小球的线程outThread、当满足消灭小球条件时将小球移除队列的线程clearThread.

JAVA多线程小游戏(java多线程实战项目)

实现代码如下:

public class First {

public void FirstUI(){

JFrame firFra=new JFrame();

firFra.setSize(800,800);

firFra.setLocationRelativeTo(null);

firFra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//FlowLayout flow=new FlowLayout();

//firFra.setLayout(flow);

firFra.setVisible(true);

Graphics g=firFra.getGraphics();

Firlistener firlis=new Firlistener(g);

firFra.addMouseListener(firlis);

firFra.addMouseMotionListener(firlis);

ImageIcon pic=new ImageIcon("C:\\Users\\user\\Desktop\\1.jpg");

Image dd=pic.getImage();

g.drawImage(dd,0,0,firFra.getWidth(),firFra.getHeight(),firFra);

}

public static void main(String []args){

First fir=new First();

fir.FirstUI();

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

继承MouseAdapter类,这样就可以只重写需要重写的函数,而不用把MouseListener, MouseWheelListener, MouseMotionListener单个类的函数都重写一遍,比如本程序只用到mouseClicked(MouseEvent e)、mouseDragged(MouseEvent e)两个函数,便不用把其他没用到的函数都重写一次。

public class Firlistener extends MouseAdapter{

Graphics g;

inThread in;

int count = 0;//

private ArrayList<Ball> listBall = new ArrayList<Ball>();

private Ball ball=new Ball();

outThread out;

public Firlistener(Graphics g){

this.g=g;

}

//创建小球,显示小球

public void mouseClicked(MouseEvent e){

ball.x=e.getX();

ball.y=e.getY();

Ball bb=new Ball();

listBall.add(bb);

if(in==null){

in=new inThread(listBall);

in.start();

out=new outThread(listBall,g,ball);

out.start();

clearThread clc=new clearThread();

clc.setclear(listBall, ball);

clc.start();

}

}

public void mouseDragged(MouseEvent e){

ball.x=e.getX()-60;

ball.y=e.getY()-60;

// ball.size=60;

out.setout(listBall, g, ball);

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

小球类,包括小球的位置、半径、颜色、运动等信息

public class Ball {

private int vx, vy, n = 0;

public int x,y,size;

Random ran = new Random();

Color color = new Color(ran.nextInt(256), ran.nextInt(256), ran.nextInt(256));

public void setdata() {

x = ran.nextInt(620) + 40;

y = ran.nextInt(620) + 40;

size = ran.nextInt(40) + 20;

vx = ran.nextInt(10);

vy = ran.nextInt(10);

vx = 5 - vx;

vy = 5 - vy;

}

public void setball(int x, int y, int size) {

this.x = x;

this.y = y;

this.size = size;

}

public void paintball(Graphics g) {

// Color color=new Color(ys%256,ys%256,ys%256);

g.setColor(color);

g.fillOval(x, y, size, size);

// System.out.println("x:"+x+"********y:"+y+"*****size:"+size);

}

public void drawball(Graphics g) {

if (n == 0) {

setdata();

n++;

}

if (x <= 40 || x >= 760)

vx = -vx;

if (y <= 40 || y >= 760)

vy = -vy;

x = x + vx;

y = y + vy;

//Color color = new Color(ran.nextInt(256), ran.nextInt(256), ran.nextInt(256));

g.setColor(color);

g.fillOval(x-size, y-size, size, size);

}

public int getx() {

return x;

}

public int gety() {

return y;

}

public int getsize() {

return size;

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

控制产生随机小球,并把产生的随机小球存储在listBall队列中,由于这里的listBall只是类似于地址指针,并没有具体的存储空间,当监听器中的listBall将地址传过来便可以进行操作了,这样可以保证所有线程操作的listBall队列是同一个数据、当一个线程将数据改变之后可以保证数据同步。同理,在outThread、clearThread线程中也是用的同样的方法保证数据同步。

public class inThread extends Thread{

private ArrayList<Ball> listBall;

public inThread(ArrayList<Ball> listBall){

this.listBall=listBall;

}

public void run(){

Ball bb=new Ball();

listBall.add(bb);

while(true){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

if(listBall.size()<=3){

Ball ball=new Ball();

listBall.add(ball);

}

}

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

由于三个线程中同时用到了listBall队列,当两个线程都要调用这个数据时就会出错,为了保证其中一个线程调用时其他程序不能调用listBall,需要用到synchronized (listBall)对listBall进行锁定,保证当本线程调用时其他线程无法使用listBall队列。同理,clearThread线程也有同样的处理方法。

public class outThread extends Thread{

private ArrayList<Ball> listBall;

private Ball ball;

private Graphics g;

public outThread(ArrayList<Ball> listBall,Graphics g,Ball ball){

this.listBall=listBall;this.ball=ball;

this.g=g;

}

public void setout(ArrayList<Ball> listBall,Graphics g,Ball ball){

this.listBall=listBall;this.ball=ball;

this.g=g;

}

@Override

public void run() {

int big=0;

while(true){

try {

Thread.sleep(40);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

ImageIcon pic=new ImageIcon("C:\\Users\\user\\Desktop\\1.jpg");

Image dd=pic.getImage();

g.drawImage(dd,0,0,800,800,null);

//g.setColor(Color.WHITE);

//g.fillRect(0, 0, 800, 800);

synchronized (listBall) {

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

Ball bal = listBall.get(i);

//改变控制球的大小

if(big==1){

ball.setball(ball.getx(), ball.gety(), ball.getsize()-1);

if(ball.getsize()<=40){big=0;}

}else if(big==0){

ball.setball(ball.getx(), ball.gety(), ball.getsize()+1);

if(ball.getsize()>=120){big=1;}

}

bal.drawball(g);

}

}

ball.paintball(g);

}

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

public class clearThread extends Thread {

private ArrayList<Ball> listBall;

private Ball ball;

public void setclear(ArrayList<Ball> listBall, Ball ball) {

this.listBall = listBall;

this.ball = ball;

}

public void run() {

while (true) {

// if(listBall!=null){

synchronized (listBall) {

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

Ball bal = listBall.get(i);

System.out.println("absx:" + Math.abs(bal.getx() - ball.getx()));

System.out.println("absy:" + Math.abs(bal.gety() - ball.gety()));

if (Math.abs(bal.getx() - ball.getx()) <= ball.getsize()

&& Math.abs(bal.gety() - ball.gety()) <= ball.getsize()) {

System.out.println("ball.x=" + bal.getx() + "ball.y" + bal.gety());

listBall.remove(bal);

}

}

// }

}

try {

Thread.sleep(40);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表