菜鸟如何零基础写一个小游戏2
在实现了上一篇的效果以后我们可以再更完善这个项目这次需要实现的效果有1利⽤线程控制⼦弹的运动2通过键盘j 发射⼦弹3按空格键⽣成⼀个玩家⻆⾊(填充正⽅形)4通过WASD控制玩家角色的移动step 1对游戏主界面的设置这是上一次设置的界面public class GameUI { public void initUI(){ JFrame jf new JFrame(游戏界面); jf.setSize(800,800); jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(3); jf.getContentPane().setBackground(Color.WHITE); //]给窗体对象的内容层set颜色 jf.setVisible(true); public Graphics g; } public static void main(String[] args) { GameUI ui new GameUI(); ui.initUI(); } }我们会发现我们的操作都是在JFrame类窗体对象jf上操作的这样到后期会影响游戏的性能动画效果等于是我们对其进行改进新new一个JPanel类对象jp我们将操作放在jp上其余保持不变JFrame jf new JFrame(游戏界面); jf.setSize(800,800); jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(3); JPanel jp new JPanel(); jp.setBackground(Color.WHITE); jf.add(jp,BorderLayout.CENTER); jf.setVisible(true); Graphics g jp.getGraphics();step 2为了让代码逻辑更清晰后期更好管理维护我们在新定义两个类一个是我们的Gamer玩家类还有一个Bulle子弹类并且子弹较多我们new一个动态数组来保存管理子弹public class Gamer { public Graphics g; public int x ,y ,size; public int speedX,speedY; //用于控制玩家的移动 public Gamer(int x,int y){ this.x x; this.y y; size 100; } }public class Bullet { public int x, y,speedX,speedY-10; public Graphics g; public Bullet(int x,int y) { this.x x; this.y y; } }同时添加GameThread类中的参数修改我们的构造函数public Graphics g; public int x,y; public Bullet bullet; public Gamer gamer ; public ArrayListBullet bullets new ArrayList();; public GameThread(Graphics g,Gamer gamer,ArrayListBullet bullets){ this.g g; this.gamer gamer; this.bullets bullets; }step 3接下来就来实现我们想要的效果由于我们想要用键盘来操控所以监听器也需要换成KeyListener键盘监听器GameListener listener new GameListener(g); jp.addKeyListener(listener);在GameListener中同样也需要继承KeyAdapter并初始化属性写构造方法重写KeyListener里的抽象方法public class GameListener extends KeyAdapter { public Graphics g; public int code; public Gamer gamer new Gamer(400,400); public ArrayListBullet bullets new ArrayList(); public GameThread gt ; public GameListener(Graphics g){ this.g g; }public void keyPressed(KeyEvent e) { }在keyPressed中我们继续实现按下不同按键实现不同效果的作用由于种类较多用if语句太冗杂我们选择使用switch语句分别管理不同的实现方法public void keyPressed(KeyEvent e) { code e.getKeyCode(); //用code 变量保存按键按下来的键码用于比对验证 switch(code){ case KeyEvent.VK_W: gamer.speedX 0; gamer.speedY -50; //控制玩家的移动 break; case KeyEvent.VK_A: gamer.speedX -50; gamer.speedY 0; break; case KeyEvent.VK_S: gamer.speedX 0; gamer.speedY 50; break; case KeyEvent.VK_D: gamer.speedX 50; gamer.speedY 0; break; case KeyEvent.VK_J: Bullet bu new Bullet(gamer.x gamer.size/2-25,gamer.y); //设置参数调整子弹从玩家上方的中间发射 bullets.add(bu); //动态数组添加新的子弹对象 break; break; case KeyEvent.VK_SPACE: gt new GameThread(g,gamer,bullets); gt.start(); break; } }step 4在玩家类中添加绘制玩家和玩家移动的方法public void draw(Graphics g){ g.setColor(Color.WHITE); g.fillRect(x,y,size,size); move(); g.setColor(Color.BLACK); g.fillRect(x,y,size,size); speedX 0; speedY 0; } public void move(){ xspeedX; yspeedY; }在子弹类中添加绘制子弹的方法public void shoot(Graphics g) { g.setColor(Color.WHITE); g.fillOval(x, y-50, 50, 50); y y speedY; g.setColor(Color.RED); g.fillOval(x, y-50, 50, 50); }step 5最后在GameThread类中修改我们的run方法public void run(){ while(true) { gamer.draw(g); for (int i 0; i bullets.size(); i) { bullet bullets.get(i); bullet.shoot(g); } try { sleep(50); } catch (InterruptedException ex) { throw new RuntimeException(ex); } } }这样子就实现了我们所有想要的效果了