线程游戏1.0

线程游戏1.0
一.项目总览类名作用UI创建界面添加监听器GameListener声明对象键盘监听设置攻击与移动GameThread声明对象游戏主线程负责所有单位的移动和绘制Bullet设置子弹对象Archer设置玩家对象Spear1设置敌对对象TimeThread设置子弹自动发射AdverThread设置敌对对象出现逻辑二.UI类publicclassUI{publicvoidshowUI(){JFramejfnewJFrame();jf.setSize(800,800);jf.setTitle(游戏界面);jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.getContentPane().setBackground(Color.WHITE);***//实际承载游戏画面的界面***JPanelgamepanelnewJPanel();gamepanel.setBackground(Color.WHITE);jf.add(gamepanel,BorderLayout.CENTER);jf.setVisible(true);***//获取画板对象上的画笔对象g******Graphicsggamepanel.getGraphics();******//将g传入GameListener构造***GameListenergameListenernewGameListener(g);jf.addMouseListener(gameListener);jf.addKeyListener(gameListener);//让gamepanel获取焦点对象gamepanel.requestFocus();jf.requestFocus();}三.BulletArcherSpear1类属性一致方法不同1.以Archer为例publicclassArcher{publicGraphicsg;publicintx,y,size;publicintspeedx,speedy;publicImageIconimg;publicArcher(Graphicsg,intx,inty){this.gg;this.xx;this.yy;this.size30;this.imgnewImageIcon(C:\\Users\\admin\\IdeaProjects\\Pro26\\src\\弓手.png);}publicvoiddraw(){g.drawImage(img.getImage(),x,y,null);move();//传入speedxspeedy}//移动逻辑publicvoidmove(){xspeedx;yspeedy;}}2.Bullet绘制逻辑publicvoiddrawbullet(Graphicsg){speedx1;xspeedx;g.drawImage(img.getImage(),x,y,null);}}3.敌对对象移动逻辑publicvoiddrawspear1(Graphicsg){speedx0;x-speedx;g.drawImage(img.getImage(),x--,y,null);}}四.GameLIstener类1.声明各类对象创建数组privateGraphicsg;publicArrayListBulletarrayListnewArrayList();publicArcherar;publicSpear1sp1;publicBulletbullet;publicGameListenergameListener;publicArrayListSpear1spear1snewArrayList();privatebooleanarstartfalse;//判断运行状态publicGameThreadgameThread;2.构造方法***//创建GameListener对象时必须传入一个Graphics画笔对象*** public GameListener(Graphics g) { //把外部传入的画笔保存到监听器内部之后在鼠标和键盘事件里就可以使用这个画笔绘制 //this代表private Graphics g this.g g; }3.键盘监听操控玩家移动和攻击publicvoidkeyPressed(KeyEvente){intkeyCodee.getKeyCode();switch(keyCode){caseKeyEvent.VK_J:System.out.println(攻击-----);//创建子弹对象设置位置让子弹出现在玩家前面bulletnewBullet(ar.x10,ar.y40);arrayList.add(bullet);break;//通过设置速度操控方向caseKeyEvent.VK_W:System.out.println(向前移动);ar.speedy-5;break;caseKeyEvent.VK_A:System.out.println(向左移动);ar.speedx-5;break;caseKeyEvent.VK_S:System.out.println(向后移动);ar.speedy5;break;caseKeyEvent.VK_D:System.out.println(向右移动);ar.speedx5;break;caseKeyEvent.VK_SPACE:System.out.println(生成单位*****);//判断是否运行若已运行则不在运行if(!arstart){//正式创建Archer对象arnewArcher(g,10,150);//创建线程对象必须传入参数调用方法GameThreadgtnewGameThread(g,ar,sp1,arrayList,spear1s,gameListener);AdverThreadatnewAdverThread(sp1,spear1s);//强制转换因为AdverThread中无start方法newThread(at).start();this.gameThreadgt;gt.start();arstarttrue;}break;caseKeyEvent.VK_Q:System.out.println(使用技能);TimeThreadttnewTimeThread(arrayList,ar);newThread(tt).start();break;caseKeyEvent.VK_R:if(gameThread!null){gameThread.paused!gameThread.paused;System.out.println(gameThread.paused?已暂停:已继续);stop();}default://其他按键不处理break;}}OverridepublicvoidkeyReleased(KeyEvente){intkeyCodee.getKeyCode();switch(keyCode){//停止逻辑防止自动前行caseKeyEvent.VK_W:System.out.println(向前移动);ar.speedy0;break;caseKeyEvent.VK_A:System.out.println(向左移动);ar.speedx0;break;caseKeyEvent.VK_S:System.out.println(向后移动);ar.speedy0;break;caseKeyEvent.VK_D:System.out.println(向右移动);ar.speedx0;break;default://其他按键不处理break;}}五.GameThread类1.声明变量publicclassGameThreadextendsThread{//成员变量只声明暂时是空引用publicGraphicsg;publicArcherar;publicSpear1sp1;publicArrayListBulletarrayList;publicArrayListSpear1spear1s;publicGameListenergameListener;//构造方法publicGameThread(Graphicsg,Archerar,Spear1sp1,ArrayListBulletarrayList,ArrayListSpear1spear1s,GameListenergameListener){***//将已存在的对象全部传入线程只传递引用地址实现数据共享***this.gg;this.arar;this.sp1sp1;this.arrayListarrayList;this.spear1sspear1s;this.gameListenergameListener;}2.run方法操控各单位的绘制publicvolatilebooleanpausedfalse;publicvoidrun(){System.out.println(Thread.currentThread().getName():线程启动...);//无限循环while(true){try{Thread.sleep(20);}catch(InterruptedExceptionex){thrownewRuntimeException(ex);}if(paused)continue;//遍历数组绘制对象for(inti0;iarrayList.size();i){BulletbulletarrayList.get(i);bullet.drawbullet(g);}for(inti0;ispear1s.size();i){Spear1spear1spear1s.get(i);spear1.drawspear1(g);}//重绘画面但会引起闪烁g.setColor(Color.WHITE);g.fillRect(0,0,1000,1000);//调用玩家绘制逻辑并实现移动ar.draw();}}}六.TimeThread1.声明变量publiclongtime;publicArcherar;publicArrayListBulletarrayList;publicTimeThread(ArrayListBulletarrayList,Archerar){this.arrayListarrayList;this.arar;this.time5;}2.run方法publicvoidrun(){while(true){try{Thread.sleep(time);}catch(InterruptedExceptione){thrownewRuntimeException(e);}//不断创建bullet对象以此实现自动发射BulletbulletnewBullet(ar.x10,ar.y40);//插入数组arrayList.add(bullet);}}}七.AdverThread1.声明变量publicclassAdverThreadimplementsRunnable{publiclongtime;publicSpear1sp1;publicArrayListSpear1spear1s;publicAdverThread(Spear1sp1,ArrayListSpear1spear1s){this.sp1sp1;this.spear1sspear1s;this.time3000;}2.run方法publicvoidrun(){***//随机数必须设置在循环外否则对象无法随机出现***RandomranewRandom(600);***//设置随机次数而非范围***intx650while(true){try{//控制出现频率此时为3秒出现一次Thread.sleep(time);}catch(InterruptedExceptione){thrownewRuntimeException(e);}intyra.nextInt(600)60;Spear1spnewSpear1(x,y);spear1s.add(sp);System.out.println(x:xy:y);}}}八.扩展1.继承与接口继承是我是一个单继承接口是我能做多实现2.标志位控制Flag Control用一个 boolean 变量作为开关控制线程循环是否执行业务逻辑本次暂停功能就是由此实现、caseKeyEvent.VK_R://判断gameThread运行状态if(gameThread!null){gameThread.paused!gameThread.paused;System.out.println(gameThread.paused?已暂停:已继续);stop();}publicvolatilebooleanpausedfalse;// 标志位while(true){if(paused)continue;// 标志位为 true 时跳过// 业务逻辑...}