JAVA多线程小游戏

JAVA多线程小游戏

首页枪战射击多线程更新时间:2024-04-29

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

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

实现代码如下:

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();

}

}

继承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);

}

}

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

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%6,ys%6,ys%6);

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;

}

}

控制产生随机小球,并把产生的随机小球存储在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);

}

}

}

}

由于三个线程中同时用到了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);

}

}

}

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();

}

}

}

}

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved