Site Search:

MonitorVehicleTrackerDemo.java



/*press arrow key to move, press space key to shoot*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

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

/*******game graphics********/
public class MonitorVehicleTrackerDemo {
    static final Random rd = new Random();
    static final int TOTALENEMIES = 20;
    static final int ENEMYMOVINGSPEED = 10;

    public static void main(String[] args) {

        JFrame mainFrame = new JFrame("Concurrency");
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setBounds(10, 10, 400, 400);
        mainFrame.setLayout(new BorderLayout());

        JPanel mainPanel = new JPanel();
        mainPanel.setBackground(Color.WHITE);

        Map<String, MutablePoint> locations = new HashMap<>();
        for(int i = 0; i < TOTALENEMIES; i++) {
            locations.put("tank" + i, new MutablePoint());
        }
        final MonitorVehicleTracker mt = new MonitorVehicleTracker(locations);
        final GameBoard paintPanel = new GameBoard(mt);

        mainFrame.add(mainPanel, BorderLayout.PAGE_START);
        mainFrame.add(paintPanel, BorderLayout.CENTER);

        mainFrame.setVisible(true);
       
        Thread tankMoveThread = new Thread(
                new Runnable(){
                    @Override
                    public void run() {
                        while(!Thread.currentThread().isInterrupted()) {
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            Map<String, MutablePoint> locations = mt.getLocations();
                            for(String key: locations.keySet()) {
                                MutablePoint mp = mt.getLocation(key);
                                mp.x += rd.nextInt(ENEMYMOVINGSPEED) * (Math.random() > 0.5 ? 1 : -1);
                                mp.y += rd.nextInt(ENEMYMOVINGSPEED) * (Math.random() > 0.5 ? 1 : -1);
                                if(mp.x > 400 - 20 || mp.y > 400 - 25 || mp.x < 20 || mp.y < 25)
                                    mp.x = mp.y = 100;
                                mt.setLocation(key, mp.x, mp.y, mp.alive);
                            }
                            paintPanel.repaint();
                        }
                    }
                });
        tankMoveThread.start();
       
        Thread waveThread = new Thread(
                new Runnable(){
                    @Override
                    public void run() {
                        while(!Thread.currentThread().isInterrupted()) {
                            try {
                                Thread.sleep(10000);
                                for(int i = 0; i < 50; i++) {
                                    Thread.sleep(100);
                                    Map<String, MutablePoint> locations = mt.getLocations();
                                    for(String key: locations.keySet()) {
                                        MutablePoint mp = mt.getLocation(key);
                                        mp.y += 5;
                                        mt.setLocation(key, mp.x, mp.y, mp.alive);
                                    }
                                    paintPanel.repaint();
                                }
                                   
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
        waveThread.start();
    }
}

class GameBoard extends JPanel implements KeyListener {
    int dx = 200;
    int dy = 300;
    int lazerBeam = 0;
    public Rectangle2D rec = new Rectangle2D.Double(dx , dy, 30, 10);
    public Rectangle2D lazer = new Rectangle2D.Double(dx + 15 , 0, 0, 0);
    private MonitorVehicleTracker mt;
   
    public GameBoard(MonitorVehicleTracker mt) {
        this.addKeyListener(this);
        this.setBackground(Color.white);
        this.setFocusable(true);
        this.mt = mt;
    }

    public void shoot(KeyEvent evt){
        if (evt.getKeyCode() == KeyEvent.VK_SPACE){
            System.out.println("space key");
        }
        lazerBeam = 300;
        lazer.setRect(dx + 15 , 0, 0, lazerBeam);
        repaint();
    }

    public void moveRec(KeyEvent evt){
        lazerBeam = 0;
        switch(evt.getKeyCode()){
            case KeyEvent.VK_LEFT:
                //System.out.println("test");
                dx -= 2;
                rec.setRect(dx, dy, 30, 10);
                lazer.setRect(dx + 15 , 0, 0, lazerBeam);
                repaint();
                break;
            case KeyEvent.VK_RIGHT:
                dx += 2;
                rec.setRect(dx, dy, 30, 10);
                lazer.setRect(dx + 15 , 0, 0, lazerBeam);
                repaint();
                break;
        }
    }  

    @Override
    protected void paintComponent(Graphics grphcs){
        cleanDead();
        super.paintComponent(grphcs);
        Graphics2D gr = (Graphics2D) grphcs;
        rec.setRect(dx, dy, 30, 10);
        lazer.setRect(dx + 15 , 0, 0, lazerBeam);
        gr.draw(rec);
        gr.draw(lazer);
        Map<String, MutablePoint> locations = mt.getLocations();
        for(String key: locations.keySet()) {
            MutablePoint mp = mt.getLocation(key);
            if(mp.alive)
                drawTank(grphcs, mp.x, mp.y);
        }
    }
   
    private void drawTank(Graphics g, int x, int y) {
        g.setColor (Color.yellow);
        g.draw3DRect (x, y, 20, 25, true);
        g.draw3DRect (x+10, y+12, 2, 25, false);
    }
   
    private void cleanDead() {
        Map<String, MutablePoint> locations = mt.getLocations();
        for(String key: locations.keySet()) {
            MutablePoint mp = mt.getLocation(key);
            if(!mp.alive) continue;
            if(overlaps(mp.x, mp.y, 20, 25, rec)
                    || overlaps(mp.x + 10, mp.y + 12, 2, 25, rec)) {
                mt.setLocation(key, mp.x, mp.y, false);
                lazerBeam = 0;
                dx = dy = -100;
            }
            if(overlaps(mp.x, mp.y, 20, 25, lazer)
                    || overlaps(mp.x + 10, mp.y + 12, 2, 25, lazer)) {
                mt.setLocation(key, mp.x, mp.y, false);
            }
        }
    }
   
    private boolean overlaps (int x, int y, int width, int height, Rectangle2D r) {
        return x < r.getX() + r.getWidth()
                && x + width > r.getX()
                && y < r.getY() + r.getHeight()
                && y + height > r.getY();
    }


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


    @Override
    public void keyPressed(KeyEvent e) {
        moveRec(e);

    }

    @Override
    public void keyReleased(KeyEvent e) {
        lazerBeam = 0;
        lazer.setRect(dx + 15 , 0, 0, lazerBeam);
        repaint();
        int i = 0;
        Map<String, MutablePoint> locations = mt.getLocations();
        for(String key: locations.keySet()) {
            MutablePoint mp = mt.getLocation(key);
            if(!mp.alive)
                i ++ ;
        }
        System.out.println(i + " tanks destroied");
    }
}

/*********game engine**********/
class MonitorVehicleTracker {
    private final Map<String, MutablePoint> locations;

    public MonitorVehicleTracker(Map<String, MutablePoint> locations) {
        this.locations = deepCopy(locations);
    }

    public synchronized Map<String, MutablePoint> getLocations() {
        return deepCopy(locations);
    }

    public synchronized MutablePoint getLocation(String id) {
        MutablePoint loc = locations.get(id);
        return loc == null ? null : new MutablePoint(loc);
    }

    public synchronized void setLocation(String id, int x, int y, boolean alive) {
        MutablePoint loc = locations.get(id);
        if (loc == null)
            throw new IllegalArgumentException("No such ID: " + id);
        loc.x = x;
        loc.y = y;
        loc.alive = alive;
    }
   
    private static Map<String, MutablePoint> deepCopy(Map<String, MutablePoint> m) {
        Map<String, MutablePoint> result = new HashMap<String, MutablePoint>();

        for (String id : m.keySet())
            result.put(id, new MutablePoint(m.get(id)));

        return Collections.unmodifiableMap(result);
    }
}

class MutablePoint {
     public int x, y;
     public boolean alive;

     public MutablePoint() {
         x = 0;
         y = 0;
         alive = true;
     }

     public MutablePoint(MutablePoint p) {
         this.x = p.x;
         this.y = p.y;
         this.alive = p.alive;
     }
 }