有关简单弹幕射击游戏的开发思路
发布时间:2026/8/13 12:41:13 作者:尧图编辑部 阅读量:1,286

简单弹幕射击游戏的开发弹幕射击游戏区别于其他的特点是其需要运用多线程的开发思路需要了解并灵活运用并发与并行线程和进程的相关知识一游戏界面的设计//创建窗口对象JframejfnewJFrame();jf.setTitle(游戏界面”);//标题jf.setSize(900,900);jf.setLocationRelativeTo(null);//窗口居中显示//点关闭按钮是时程序终止运行jf.setDefaultCloseOperation(3);JPaneljpnewJPanel();//创建面板jp.setBackground(Color.WHITE);jf.add(jp,BorderLayout.CENTER);jf.setVisible(true);Graphicsgjp.getGraphics();//获取面板的绘图对象GameListenerlistenernewGamelistener();jf.addKeyListener(listener);//添加键盘监听器//将键盘焦点设置到面板上jp.requestFocus();特别注意设置焦点的原因是键盘事件只有焦点组件才能接收而JPanel可以获取焦点但是不会自动获取二事件监听器2.1GameListener类实现键盘监听器额接口,并重写其抽象方法publicclassGameListnenerimplementsKeyListener{publicvoidkeyTyped(KeyEvente){}publicvoidkeyPressed(KeyEvente){}publicvoidkeyReleased(KeyEvente){}}2.2具体的功能实现publicvoidkeyPressed(KeyEvente){intkeye.getKeyCode();switch(key){caseKeyEvent.VK_SPACE:System.out.println(空格被按下);rolenewRole(350,600);GameThreadthreadnewGameThread(g,role,arrayList,this);thread.start();break;caseKeyEvent.VK_J:System.out.println(发射子弹);BulletbulletnewBullet(role.xrole.size/2,role.y);arrayList.add(bullet);break;caseKeyEvent.VK_W:System.out.println(向上移动);role.speedY-5;break;caseKeyEvent.VK_S:System.out.println(向下移动);role.speedY5;break;caseKeyEvent.VK_A:System.out.println(向左移动);role.speedX-5;break;caseKeyEvent.VK_D:System.out.println(向右移动);role.speedX5;break;caseKeyEvent.VK_B:System.out.println(切换开火方式);b!b;}}publicvoidkeyTyped(KeyEvente){}publicvoidkeyReleased(KeyEvente){intkeye.getKeyCode();switch(key){caseKeyEvent.VK_W:System.out.println(向上移动结束);role.speedY0;caseKeyEvent.VK_S:System.out.println(向下移动结束);role.speedY0;caseKeyEvent.VK_A:System.out.println(向左移动结束);role.speedX0;caseKeyEvent.VK_D:System.out.println(向右移动结束);role.speedX0;}}特别注意1.使用switch case结构来处理不同按键功能2.使用速度值控制方向正负值代表方向3.松键是速度归零实现停止三游戏主线程GameThreadpublicvoidrun(){System.out.println(Thread.currentThread().getName()线程已启动);while(true){try{Thread.sleep(10);}catch(InterruptedExceptione){thrownewRuntimeException(e);}if(listener.btrue){count;if(count3){BulletbulletnewBullet(role.xrole.size/2,role.y);arrayList.add(bullet);count0;}}role.drawRole(g);for(inti0;iarrayList.size();i){BulletbulletarrayList.get(i);bullet.drawBullet(g);bullet.move();}}}特别注意1.使用while(true)无限循环保证游戏正常运行2.Thread.sleep控制速度3.自动开火时计数器控制开火速度四定时任务线程TimeThreadpubliclongtime200;publicRolerole;publicArrayListBulletbullets;publicbooleanrunningtrue;publicTimeThread(ArrayListBulletbullets,Rolerole){this.bulletsbullets;this.rolerole;}publicvoidrun(){while(running){try{Thread.sleep(time);}catch(InterruptedExceptione){thrownewRuntimeException(e);}BulletbulletnewBullet(role.xrole.size/2,role.y);bullets.add(bullet);}}publicvoidstopBullet(){runningfalse;}五角色类RolepublicvoiddrawRole(Graphicsg){g.setColor(Color.WHITE);g.fillRect(x,y,size,size);// 更新位置move();// 黑色实体g.setColor(Color.BLACK);g.fillRect(x,y,size,size);}六子弹类Bullet)publicvoiddrawBullet(Graphicsg){// 红色子弹主体g.setColor(Color.RED);g.fillRect(x,y,size,size);// 白色子弹用来消除轨迹g.setColor(Color.WHITE);g.fillRect(x,yspeed,size,size);}七敌机类EnemyPlane// 存放所有敌机的列表ArrayListEnemylistnewArrayList();// 计数器控制多久生成一个敌机intcount0;classEnemy{intx(int)(Math.random()*800);inty-40;intsize40;intspeed2;intoldXx;// 记录旧位置初始等于当前位置intoldYy;// 向下移动voidmove(){oldXx;oldYy;yyspeed;}// 画出自己voiddraw(Graphicsg){g.setColor(Color.WHITE);g.fillRect(oldX,oldY,size,size);//消除敌机尾迹g.setColor(Color.RED);g.fillRect(x,y,size,size);}// 判断是否超出屏幕底部booleanisOut(){if(y800){returntrue;}else{returnfalse;}}}//更新所有敌机voidupdate(){// 每60帧生成一个敌机countcount1;if(count60){count0;EnemyenewEnemy();list.add(e);}// 让所有敌机移动超出屏幕的删掉// 倒着数从最后一个到第一个intilist.size()-1;// 最后一个的位置while(i0){Enemyelist.get(i);// 取出第i个敌机e.move();// 让它往下走if(e.isOut()){// 如果超出屏幕了list.remove(i);// 删掉它}ii-1;// 看前一个}}// 画出所有敌机 voiddraw(Graphicsg){// 用普通循环从第一个到最后一个inti0;while(ilist.size()){Enemyelist.get(i);// 取出第i个敌机e.draw(g);// 让它画出自己ii1;// 看下一个}}