十六是只仙 发表于 2017-3-27 23:29:02

震惊!为何这辆坦克......

我们老师丧心病狂惨无人道.....
让我们用java写出一个坦克大战游戏
现在做了一共三个函数
主函数中键盘移动有问题{:10_266:} {:10_266:}



TankGameWindow
Tank
TankWindow(主函数)

import java.awt.Color;
import java.awt.Frame;
import java.awt.event.*;
import java.awt.color.*;
import java.awt.Graphics;
        public class TankGameWindow extends Frame{
                Tank tank;
               
                public void initFrame(){
                        this.setVisible(true);
                        this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
                        this.setSize(800,500);
                        this.setTitle("CRAZY TANK");
                        this.setResizable(false);
                        this.setBackground(Color.green);
                        this.addWindowListener(new WindowAdapter()
                        {
                                public void windowClosing(WindowEvent e){
                                        System.exit(0);
                                }
                        });
                        tank=new Tank(300,300,Color.red);
                        Thread t;
                        t=new Thread(new PaintThread());
                        t.start();
                }
       
               
                //坦克反复擦掉重画
                private class PaintThread implements Runnable
                {
                        public void run()
                        {
                                while(true)
                                {
                                        repaint();
                                        try{
                                                Thread.sleep(50);//间隔50mm画
                                        }catch(InterruptedException e)
                                        {
                                                e.printStackTrace();
                                        }
                                }
                        }
                }
                public void paint(Graphics g){
                        tank.draw(g);
                }
        }



import java.awt.Color;
import java.awt.Graphics;
public class Tank {
        int x,y;
        byte state=1;//状态
        public final int WIDTH=20;
        public final int HIGHT=20;
        Color tankColor;
        public Tank(int ax,int ay,Color ac){
                x=ax;
                y=ay;
                tankColor=ac;
        }
       
        //move坦克
        public void move(){
                state--;
                if(state<1)
                        state=3;
        }
        public void draw(Graphics g){
                move();
                Color c=g.getColor();
                drawBody(g,x,y,Color.RED);
                drawTrack(state,g,x,y,Color.RED);
                g.setColor(c);
        }
        public void drawTrack(int a,Graphics g,int x,int y,Color c){
                g.setColor(c);
          for(int i=a;i<=28;i=i+3)
          {
                  g.drawLine(x-13,y-14+i,x-11,y-14+i);//画出履带上的直线
                  g.drawLine(x+11,y-14+i,x+13,y-14+i);
          }
        }
        public void drawBody(Graphics g,int x,int y,Color c){
                g.setColor(c);
                g.drawRect(x-10,y-10,20,20);
                g.drawOval(x-8,y-8,16,16);
                g.drawRect(x-1,y-24,2,24);//坦克的身体
                g.drawRect(x-14,y-14,4,28);
                g.drawRect(x+10,y-14,4,28);
                }
}






import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class TankWindow {
               
                       TankMove Movea = null;
       
        public static void main(String args[]){
                        TankGameWindow window=new TankGameWindow();
                        window.initFrame();
                       Movea = new TankMove();//这里new的时候报错
}
       
        //通过键盘控制坦克移动但无法实现
       
           class TankMove implements KeyListener{
                int x =300;
                int y = 300;
                Tank tank = new Tank(x,y,Color.red);
                @Override
                public void keyPressed(KeyEvent e) {
                       
                        if(e.getKeyCode()==KeyEvent.VK_DOWN){
                                x-=3;
                        }else if(e.getKeyCode()== KeyEvent.VK_UP){
                                y-=3;
                        }else if(e.getKeyCode()== KeyEvent.VK_LEFT){
                                x-=3;
                        }else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
                                x+=3;
                        }
                        //调用repain函数,来重画界面
                        Tank tank = new Tank(x,y,Color.red);
                       
                }
               



                @Override
                public void keyReleased(KeyEvent e) {
                }

                @Override
                public void keyTyped(KeyEvent e) {
                }
           }
}
       






zlj19931010 发表于 2017-3-28 09:31:44

......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了

还是别的错?你把错误讲清楚{:10_277:}

zlj19931010 发表于 2017-3-28 15:07:17

Direction
package tank;

public enum Direction {
        UP(0),
        DOWN(2),
        LEFT(3),
        RIGHT(1);
        private int value;
        private Direction(int value){
                this.value = value;
        }
       
        public int getValue(){
                return this.value;
        }
}

Point
package tank;

import java.util.Random;

public class Point {
        int x;
        int y;
       
        public Point(int x, int y) {
                super();
                this.x = x;
                this.y = y;
        }
        public int getX() {
                return x;
        }
        public void setX(int x) {
                this.x = x;
        }
        public int getY() {
                return y;
        }
        public void setY(int y) {
                this.y = y;
        }
       
        public void rotation(Direction direction,Point center){
       
                int h = center.getY() - y;
                int w = center.getX() - x;
            switch(direction){
            case UP:
                    //向上不用变化
                    break;
            case RIGHT:
                    //翻转90°
                    x += h + w;
                    y = center.getY() - w;
                    break;
            case DOWN:
                    //翻转180°,x不变,y变化
                    //其实,这边也是不用变的,反正上下都看不出
                    x = center.getX() + w;
                    y = center.getY() + h;
                    break;
            case LEFT:
                    //翻转270°
                    x += h + w;
                    y = center.getY() - w;
                    break;
            }
    }
        @Override
        public String toString() {
                return "Point ";
        }
       
}


Tank
package tank;

import java.awt.Color;
import java.awt.Graphics;

public class Tank {
        int x,y;
    byte state=1;//状态
    Direction direction = Direction.UP;//默认的是向上的方向
    public final int WIDTH=20;
    public final int HIGHT=20;
    Color tankColor;
   
        public Direction getDirection() {
                return direction;
        }

        public void setDirection(Direction direction) {
                this.direction = direction;
        }

        public Tank(int ax,int ay,Color ac){
      x=ax;
      y=ay;
      tankColor=ac;
    }
   
    //move坦克
    public void move(){
          state--;
          if(state<1)
                  state=3;
    }
    public void draw(Graphics g){
          move();
          Color c=g.getColor();
          drawBody(g,x,y,Color.RED);
          drawTrack(state,g,x,y,Color.RED);
          g.setColor(c);
    }
    public void drawTrack(int a,Graphics g,int x,int y,Color c){
      g.setColor(c);
      for(int i=a;i<=28;i=i+3)
      {
              drawLine(g,x-13,y-14+i,x-11,y-14+i);//画出履带上的直线
              drawLine(g,x+11,y-14+i,x+13,y-14+i);
      }
    }
    public void drawBody(Graphics g,int x,int y,Color c){
          g.setColor(c);
          g.drawRect(x-10,y-10,20,20);
          g.drawOval(x-8,y-8,16,16);
          drawRect_body(g,x-1,y-24,2,24);//坦克的身体
          drawRect_left(g,x-14,y-14,4,28);
          drawRect_right(g,x+10,y-14,4,28);
    }
   
    private void drawLine(Graphics g, int x1, int y1, int x2, int y2){
            //绘制之前首先翻转坐标
            Point p1 = new Point(x1,y1);
            Point p2 = new Point(x2,y2);
            p1.rotation(direction, getCenterPoint());
            p2.rotation(direction, getCenterPoint());
           
            g.drawLine(p1.getX(),p1.getY(), p2.getX(),p2.getY());
    }
   
    private void drawRect_left(Graphics g,int x, int y, int width, int height){
            int temp;
            switch (direction) {
                case UP:
                       
                        break;
                case RIGHT:
                        temp = width;
                        width = height;
                        height = temp;
                        break;
                case DOWN:
                        break;
                case LEFT:
                        temp = width;
                        width = height;
                        height = temp;
                        break;
                }
            g.drawRect(x,y,width,height);//坦克的身体
    }
   
    private void drawRect_right(Graphics g,int x, int y, int width, int height){
            int temp;
            switch (direction) {
                case UP:
                       
                        break;
                case RIGHT:
                        x -= 24;
                        y += height-width;
                       
                        temp = width;
                        width = height;
                        height = temp;
                        break;
                case DOWN:
                       
                        break;
                case LEFT:
                        x -= 24;
                        y += height-width;
                       
                        temp = width;
                        width = height;
                        height = temp;
                        break;
                }
            g.drawRect(x,y,width,height);//坦克的身体
    }
   
    private void drawRect_body(Graphics g,int x, int y, int width, int height){
            int temp;
            switch (direction) {
                case UP:
                        break;
                case RIGHT:
                        y += height;
                        temp = width;
                        width = height;
                        height = temp;
                        break;
                case DOWN:
                        y += height;
                        break;
                case LEFT:
                        y += height;
                        x -= height;
                        temp = width;
                        width = height;
                        height = temp;
                        break;
                }
            g.drawRect(x,y,width,height);//坦克的身体
    }
   
    /**
   * 返回当前tank 的中点坐标
   * @return
   */
    public Point getCenterPoint(){
            return new Point(x, y);
    }

        public int getX() {
                return x;
        }

        public void setX(int x) {
                this.x = x;
        }

        public int getY() {
                return y;
        }

        public void setY(int y) {
                this.y = y;
        }
   
   
}


TankGameWindow
package tank;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

@SuppressWarnings("serial")
public class TankGameWindow extends Frame{
        Tank tank;
   
    public void initFrame(){
      this.setVisible(true);
      this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
      this.setSize(800,500);
      this.setTitle("CRAZY TANK");
      this.setResizable(false);
      this.setBackground(Color.green);
      this.addKeyListener(new KeyListener() {
                       
                        @Override
                        public void keyTyped(KeyEvent e) {
                               
                        }
                       
                        @Override
                        public void keyReleased(KeyEvent e) {
                               
                        }
                       
                        @Override
                        public void keyPressed(KeyEvent e) {
                        if(e.getKeyCode()==KeyEvent.VK_DOWN){
                                tank.setY(tank.getY() + 3);
                                tank.setDirection(Direction.DOWN);
                     }else if(e.getKeyCode()== KeyEvent.VK_UP){
                          tank.setY(tank.getY() - 3);
                          tank.setDirection(Direction.UP);
                     }else if(e.getKeyCode()== KeyEvent.VK_LEFT){
                          tank.setX(tank.getX() - 3);
                          tank.setDirection(Direction.LEFT);
                     }else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
                          tank.setX(tank.getX() + 3);
                          tank.setDirection(Direction.RIGHT);
                     }
                        }
                });
      this.addWindowListener(new WindowAdapter()
      {
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
      });
      tank=new Tank(300,300,Color.red);
      Thread t;
      t=new Thread(new PaintThread());
      t.start();
    }

   
    //坦克反复擦掉重画
    private class PaintThread implements Runnable
    {
      public void run()
      {
            while(true)
            {
                repaint();
                try{
                  Thread.sleep(50);//间隔50mm画
                }catch(InterruptedException e)
                {
                  e.printStackTrace();
                }
            }
      }
    }
    public void paint(Graphics g){
      tank.draw(g);
    }
}


TankWindow
package tank;

public class TankWindow {
    public static void main(String args[]){
           
      TankGameWindow window=new TankGameWindow();
      
      window.initFrame();
    }
}


稍微修改了下,可以运行

十六是只仙 发表于 2017-3-29 00:45:10

zlj19931010 发表于 2017-3-28 09:31
......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了
...

恩.....就是这个问题,我现在修改了下,我把这个函数重新封装了下

十六是只仙 发表于 2017-3-29 00:51:15

zlj19931010 发表于 2017-3-28 09:31
......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了
...

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class TankWindow {
               
                       
       
        public static void main(String args[]){
                        TankGameWindow window=new TankGameWindow();
                        window.initFrame();
                  
}
       
}//主函数这样


import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class TankMove implements KeyListener{
        int x =300;
        int y = 300;
        Tank tank = new Tank(x,y,Color.red);
        @Override
        public void keyPressed(KeyEvent e) {
               
                if(e.getKeyCode()==KeyEvent.VK_DOWN){
                        x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_UP){
                        y-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_LEFT){
                        x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
                        x+=3;
                }
                //调用repain函数,来重画界面
                Tank tank = new Tank(x,y,Color.red);
               
        }
       



        @Override
        public void keyReleased(KeyEvent e) {
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

       
}//新建的这个Move类


import java.awt.Color;
import java.awt.Frame;
import java.awt.event.*;
import java.awt.color.*;
import java.awt.Graphics;
        public class TankGameWindow extends Frame{
                Tank tank;
                TankMove area;
                public void initFrame(){
                        this.setVisible(true);
                        this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
                        this.setSize(800,500);
                        this.setTitle("CRAZY TANK");
                        this.setResizable(false);
                        this.setBackground(Color.green);
                        this.addWindowListener(new WindowAdapter()
                        {
                                public void windowClosing(WindowEvent e){
                                        System.exit(0);
                                }
                        });
                        tank=new Tank(300,300,Color.red);
                        Thread t;
                        t=new Thread(new PaintThread());
                        t.start();
                  area = new TankMove();//将move在这里调用
                }
       
               
                //坦克反复擦掉重画
                private class PaintThread implements Runnable
                {
                        public void run()
                        {
                                while(true)
                                {
                                        repaint();
                                        try{
                                                Thread.sleep(50);//间隔50mm画
                                        }catch(InterruptedException e)
                                        {
                                                e.printStackTrace();
                                        }
                                }
                        }
                }
                public void paint(Graphics g){
                        tank.draw(g);



       
          

十六是只仙 发表于 2017-3-29 00:51:47

zlj19931010 发表于 2017-3-28 09:31
......................我复制了
Movea是TankWindow的实例属性,怎么能访问到,错误提示已经说的很清楚了
...

我想知道,可以按我这个思路修改吗.....

zlj19931010 发表于 2017-3-29 10:11:43

本帖最后由 zlj19931010 于 2017-3-29 10:17 编辑

求解在监听里面每次new个tank实例是为了什么

十六是只仙 发表于 2017-3-29 13:25:41

zlj19931010 发表于 2017-3-29 10:11
求解在监听里面每次new个tank实例是为了什么

public class TankGameWindow extends Frame{
                Tank tank;
                TankMove area;
                public void initFrame(){
                        this.setVisible(true);
                        this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
                        this.setSize(800,500);
                        this.setTitle("CRAZY TANK");
                        this.setResizable(false);
                        this.setBackground(Color.green);
                        this.addWindowListener(new WindowAdapter()
                        {
                                public void windowClosing(WindowEvent e){
                                        System.exit(0);
                                }
                        });
                        tank=new Tank(300,300,Color.red);
                        Thread t;
                        t=new Thread(new PaintThread());
                        t.start();
                        area = new TankMove();
                        this.addKeyListener(area);
               
                }
        我把监听放到下面了......




public class TankMove extends JPanel implements KeyListener{
        Tank tank;
       
        int x =300;
        int y = 300;
//        Tank tank = new Tank(x,y,Color.red);
       
//        public void paint(Graphics g){
//                tank.draw(g);
//        }
        @Override
        public void keyPressed(KeyEvent e) {
               
                if(e.getKeyCode()==KeyEvent.VK_DOWN){
                        x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_UP){
                        y-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_LEFT){
                        x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
                        x+=3;
                }
                //调用repain函数,来重画界面
//                Tank tank = new Tank(x,y,Color.red);
                this.repaint();
               
        }
       



        @Override
        public void keyReleased(KeyEvent e) {
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

       
}
move函数也改了下, 继承了Jpanel,但还是移动不了

十六是只仙 发表于 2017-3-29 13:27:05

zlj19931010 发表于 2017-3-29 10:11
求解在监听里面每次new个tank实例是为了什么

package cn.Make;

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

/*
* 功能:加深对事件机制理解
* 1.通过上下左右键来控制小球移动
* 2.
*/
public class MakeBallMove extends JFrame{
                Mypanel mp = null;
       
                public static void main(String[] args) {
                        MakeBallMove me = new MakeBallMove();
                }
               
                //构造函数
                public MakeBallMove(){
                       
                        mp = new Mypanel();
                       
                        //MP加入到JFram中
                        this.add(mp);
                        this.setSize(400,300);
                        this.setVisible(true);
                       
                        this.addKeyListener(mp);
                }
}


//定义自己的面板

class Mypanel extends JPanel implements KeyListener{
       
       
        int x = 10;
        int y = 10;
        public void paint(Graphics g){
               
               
                super.paint(g);
               
                g.fillOval(x, y, 10, 10);
        }

       
        //仅仅被压下去
        @Override
        public void keyPressed(KeyEvent e) {
//                System.out.println("啦啦啦阿拉"+(char)e.getKeyCode());
                if(e.getKeyCode()==KeyEvent.VK_DOWN){
                        y+=3;
                }else if(e.getKeyCode()== KeyEvent.VK_UP){
                        y-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_LEFT){
                        x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
                        x+=3;
                }
                //调用repain函数,来重画界面
                this.repaint();
        }

       
        //被松开
        @Override
        public void keyReleased(KeyEvent e) {
        }

        //输入具体信息
        @Override
        public void keyTyped(KeyEvent e) {
        }
}

我是模仿这个写的让他动起来

zlj19931010 发表于 2017-3-29 14:38:52

本帖最后由 zlj19931010 于 2017-3-29 14:40 编辑

...........你这个监听的 this.repaint();是重新绘制的panel,不是你tank,你要重写Jpanel里面的paint函数,然后在paint函数里绘制tank实例
1、这段放开:
//      public void paint(Graphics g){
//                tank.draw(g);
//      }

2、下面的x,y改成tank.x,tank.y(当然要在x,y是public属性),这里是要修改游戏中tank 的位置,不是panel的位置:
if(e.getKeyCode()==KeyEvent.VK_DOWN){
                        x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_UP){
                        y-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_LEFT){
                        x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
                        x+=3;
                }

你可以看我给你的代码,可以运行的,而且坦克的朝向也会根据方向变化。。

十六是只仙 发表于 2017-3-29 16:59:41

zlj19931010 发表于 2017-3-29 14:38
...........你这个监听的 this.repaint();是重新绘制的panel,不是你tank,你要重写Jpanel里面的paint函数 ...

谢谢大佬= =我就想知道我的这个可以改成功不,因为这是老师的作业在他原有基础上改让坦克动起来......

zlj19931010 发表于 2017-3-29 17:38:57

本帖最后由 zlj19931010 于 2017-3-29 17:45 编辑

十六是只仙 发表于 2017-3-29 16:59
谢谢大佬= =我就想知道我的这个可以改成功不,因为这是老师的作业在他原有基础上改让坦克动起来......

可以的,你把游戏中的tank实例传递到TankMove实例中
比如构造传入:
public TankMove (Tank tank){
    this.tank = tank;
}
然后
public void paint(Graphics g){
                tank.draw(g);
      }
然后监听器里面:
public void keyPressed(KeyEvent e) {
               
                if(e.getKeyCode()==KeyEvent.VK_DOWN){
                        tank.y += 3;
                }else if(e.getKeyCode()== KeyEvent.VK_UP){
                        tank.y -= 3;
                }else if(e.getKeyCode()== KeyEvent.VK_LEFT){
                        tank.x-=3;
                }else if(e.getKeyCode()== KeyEvent.VK_RIGHT){
                        tank.x+=3;
                }
                //调用repain函数,来重画界面
                this.repaint();
               
      }

逻辑这样是通的,你自己调试下,我就知道以前上学的时候碰到过一个repaint的坑,你已经开了一个线程在一直repaint,这里不知道会不会阻塞,忘记了

十六是只仙 发表于 2017-3-29 18:10:05

zlj19931010 发表于 2017-3-29 17:38
可以的,你把游戏中的tank实例传递到TankMove实例中
比如构造传入:
public TankMove (Tank tank){


感动世界!!!谢谢我总算弄出来了.....但是,想再请教一个小问题,我想加一个按钮....
public class TankGameWindow extends Frame implements ActionListener{
                Tank tank;
                TankMove area;
               
                public void initFrame(){
                        this.setVisible(true);
                        this.setLocation(300,300);//实现坦克大战的窗口,且填充了背景颜色
                        this.setSize(800,500);
                        this.setTitle("CRAZY TANK");
                        this.setResizable(false);
                        this.setBackground(Color.green);
               
                        this.addWindowListener(new WindowAdapter()
                        {
                                public void windowClosing(WindowEvent e){
                                        System.exit(0);
                                }
                        });
                        tank=new Tank(300,300,Color.red);
                        Thread t;
                        t=new Thread(new PaintThread());
                        t.start();
                        area = new TankMove(tank);
                        this.addKeyListener(area);
               
              JButton jb = new JButton("变色");
                        jb =new JButton("变色");
                        jb.add(jb, BorderLayout.NORTH);
                }方法应该没有弄错.....但是为什么运行出来没有按钮{:10_266:}

zlj19931010 发表于 2017-3-30 09:41:54

十六是只仙 发表于 2017-3-29 18:10
感动世界!!!谢谢我总算弄出来了.....但是,想再请教一个小问题,我想加一个按钮....
public class Ta ...

你把 jb.add(jb, BorderLayout.NORTH);
改成
this.add(jb, BorderLayout.NORTH);
this:指的是当前Frame

十六是只仙 发表于 2017-3-30 20:21:39

zlj19931010 发表于 2017-3-30 09:41
你把 jb.add(jb, BorderLayout.NORTH);
改成
this.add(jb, BorderLayout.NORTH);


JButton jb = new JButton("变色");
                        jb =new JButton("变色");
                        this.add(jb, BorderLayout.NORTH);


这样改了,还是没有变化{:10_266:}

zlj19931010 发表于 2017-3-31 09:54:29

本帖最后由 zlj19931010 于 2017-3-31 13:36 编辑

十六是只仙 发表于 2017-3-30 20:21
JButton jb = new JButton("变色");
                        jb =new JButton("变色");
                        this.add(jb, BorderLayout.NORT ...

因为你开了个绘画线程,你这个按钮一直在被覆盖绘制,你把鼠标移动到最上面会闪出来button按钮

我想想怎么解决,最近开发中有点忙......

我中午研究下,有问题。。。。

你把继承的Frame改成JFrame,你需要自定义面板,应该用JFrame

zlj19931010 发表于 2017-3-31 13:35:17

我现在改了下,一个frame,上面放操作按钮toppanel
下面是游戏界面 gamepanel

99592938 发表于 2017-4-7 20:13:46

过来膜拜
页: [1]
查看完整版本: 震惊!为何这辆坦克......