在java中同时旋转和翻译单个图像

时间:2014-05-18 14:33:43

标签: java

我正在为我的项目制作一个蛇游戏,我有一个关于同时旋转和翻译图像的问题。我的蛇沿任何方向跟随光标,我想将它的头部旋转一个光标所执行的角度。我已经尝试了很多使用仿射变换,但问题是我们可以一次使用旋转或平移功能,但不能同时使用两者。我已经给出了代码,蛇体和它的运动是由油漆组件处理的,我混淆了我应该做什么改变以获得所需的结果,如上所述。我已经通过堆栈溢出发布的文档和问题,但我没有解决方案

 import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.event.*;
import java.awt.Rectangle;
import java.awt.ComponentOrientation;
import java.awt.Font;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;

//class starts
//this class actually contains the game
//the object of this class is created in Snake_Menu class to start the real game
public class Game extends JPanel implements MouseListener, MouseMotionListener {
    JFrame jf = new JFrame();// main frame
    int x_Cur; // x_position of cursor
    int y_Cur; // y_position of cursor
    int delta_x, delta_y; // difference between x positions and y positions of
                            // cursor and snake head
    int x_positions[] = new int[3600]; // array for storing x positions of body
                                        // segments
    int y_positions[] = new int[3600]; // array for storing y positions of body
                                        // segments
    int food_x, food_y; // storing x,y positions of food
    double x_inc, y_inc;// the increment added in head positions
    int segments;// defines length of snake body
    double angle;// calculated btw cursor and snake head
    double speed = 5.0;// speed of snake
    static int counter = 0;
    int rand_loc = 500;
    BufferedImage body;// image object for body
    BufferedImage head;// image object for head
    BufferedImage bgimage;// image object for background
    Sound sound = new Sound();// object of "Sound" class
    JLabel score = new JLabel("Score:" + sc);
    JPanel controlpn = new JPanel();
    static int sc;
    static int wr = 1;
    static int start;
    JLabel pause;
    int flag = 0;
    private JLabel resume = new JLabel("Resume\r\n");
    private JLabel Back = new JLabel(" Back");
    {
        try {
            // initializing image objects
            body = ImageIO.read(new File("./Images/Body.png"));
            bgimage = ImageIO.read(new File("./Images/Back.jpg"));
            head = ImageIO.read(new File("./Images/head.png"));
        } catch (IOException ex) {
            System.out.println("Images not found");
        }
    }

    /******************************************************************************************************************************************/
    /* <<<Constructor called by class "Snake_Menu">>> */
    /*****************************************************************************************************************************************/
    // constructor starts
    public Game() {
        // sound.music_stop();//slows down background music when playing game
        jf.getContentPane().setLayout(new BorderLayout());
        JPanel jp = new JPanel();
        jp.setBorder(new LineBorder(new Color(0, 0, 0)));
        jp.setForeground(new Color(220, 20, 60));
        jp.setBackground(new Color(100, 149, 237));
        // jp.setBounds(0, 0, 600, 500);
        jp.setLayout(new BorderLayout());
        pause = new JLabel("Pause");
        pause.setFont(new Font("Bradley Hand ITC", Font.BOLD | Font.ITALIC, 20));
        pause.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        pause.addMouseListener(new MouseAdapter() {
            // actions taken when mouse enters or exits or clicked on the bounds
            @Override
            public void mouseEntered(MouseEvent e) {
                pause.setForeground(Color.red);
            }

            public void mouseExited(MouseEvent e) {
                pause.setForeground(Color.black);
            }

            public void mouseClicked(MouseEvent e) {
                flag = 1;
            }
        });

        resume.setFont(new Font("Bradley Hand ITC", Font.BOLD | Font.ITALIC, 20));
        resume.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        resume.addMouseListener(new MouseAdapter() {
            // actions taken when mouse enters or exits or clicked on the bounds
            @Override
            public void mouseEntered(MouseEvent e) {
                resume.setForeground(Color.red);
            }

            public void mouseExited(MouseEvent e) {
                resume.setForeground(Color.black);
            }

            public void mouseClicked(MouseEvent e) {
                flag = 0;
            }
        });

        Back.setFont(new Font("Bradley Hand ITC", Font.BOLD | Font.ITALIC, 20));
        Back.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        Back.addMouseListener(new MouseAdapter() {
            // actions taken when mouse enters or exits or clicked on the bounds
            @Override
            public void mouseEntered(MouseEvent e) {
                Back.setForeground(Color.red);
            }

            public void mouseExited(MouseEvent e) {
                Back.setForeground(Color.black);
            }

            public void mouseClicked(MouseEvent e) {
                sound.music_stop();
                Snake_Menu sn=new Snake_Menu();
                sn.frame.setVisible(true);
                jf.setVisible(false);
            }
        });

        controlpn.add(Back);
        controlpn.add(resume);
        controlpn.add(pause, BorderLayout.WEST);// add to frame
        controlpn.setBackground(new Color(100, 149, 237));

        score.setFont(new Font("Bradley Hand ITC", Font.BOLD | Font.ITALIC, 20));
        jp.add(score, BorderLayout.WEST);
        jp.add(controlpn, BorderLayout.EAST);
        jf.getContentPane().add(jp, BorderLayout.NORTH);

        // frame properties
        jf.getContentPane().add(this, BorderLayout.CENTER);
        jf.addMouseMotionListener(this);// adding mouse motion listener to frame
        jf.addMouseListener(this);// adding mouse listener to frame
        jf.setFocusable(true);
        jf.setSize(new Dimension(700, 650));
        jf.setResizable(false);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
        first_Snake();// this method initializes first snake
        sound.music_Bg(); // Sound Class method for playing background music
    }// constructor ends

    **/******************************************************************************************************************************************/
    /* <<<Paint Component>>> */
    /*****************************************************************************************************************************************/
    // paint starts here
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(bgimage, 0, 0,700,650, this); // drawing background image
        g2d.drawImage(body, food_x, food_y, 31, 31, this); // food image
        // this for loop paints the body
        for (int z = 0; z < segments; z++) {
            if (z == 0) {
                // do nothing
            } else if (z == 1)
                g2d.drawImage(body, x_positions[z], y_positions[z], 31, 31,
                        this);
            else
                g2d.drawImage(body, x_positions[z], y_positions[z], 31, 31,
                        this);
        }

        try {
            Thread.sleep(10);
        } catch (Exception e) {
        }
        meet_Food();// checks whether the head has met with food or not
        /*********** this block defines the motion of snake ************/
        delta_x = x_Cur - x_positions[0];
        delta_y = y_Cur - y_positions[0];
        angle = Math.atan2(delta_y, delta_x);
        double speed = Math.sqrt(delta_x * delta_x + delta_y * delta_y);
        speed = Math.min(speed, 3.0);
        if (flag != 1) {
            x_inc = (speed * Math.cos(angle));
            y_inc = (speed * Math.sin(angle));
            x_positions[0] += x_inc;
            y_positions[0] += y_inc;
        }
        counter++;// to give a gap between body segments
        // when x_positions[0] is incremented 7 times
        // then its value is passed to its body segments
        // to have a space in segments of body, counter does that job
        if (counter % 7 == 0) {
            if (!(delta_x == 0 && delta_y == 0)) {
                // this for loop transfer the positions of head to its body
                for (int z = segments; z > 0; z--) {
                    x_positions[z] = x_positions[z - 1];
                    y_positions[z] = y_positions[z - 1];
                }
            }
            counter = 0;
        }
        /*************************** block ends ***********************/
        if (start == 1)
            repaint();
    }// paint ends**

    /******************************************************************************************************************************************/
    /* <<<first_Snake method;initializes first snake>>> */
    /*****************************************************************************************************************************************/
    public void first_Snake() {
        segments = 3;
        for (int z = 0; z < segments; z++) {
            x_positions[z] = 60 - z * 20; // giving space of 20 pixels btw every
                                            // segment
            y_positions[z] = 60;
        }
    }// first_Snake ends

    /******************************************************************************************************************************************/
    /* <<< locate_Food method; to locate food at random after snake eats it>>> */
    /*****************************************************************************************************************************************/
    public void locate_Food() {
        food_x = (int) (Math.random() * rand_loc);
        food_y = (int) (Math.random() * rand_loc);
    }// locate_Food ends

    /******************************************************************************************************************************************/
    /* <<<Checks whether snake has met food or not>>>>> */
    /*****************************************************************************************************************************************/
    public void meet_Food() {
        for (int y = 1; y < 31; y++) {
            if ((x_positions[1] >= food_x && x_positions[1] <= food_x + 31)
                    && (y_positions[1] + y >= food_y & y_positions[1] + y <= food_y + 31)) {
                sound.music_Eat();
                sc += 5;
                score.setText("Score:" + sc);
                segments++;
                locate_Food();
            }
        }
    }// meet_Food ends

    @Override
    public void mouseDragged(MouseEvent me) {
    }

    /******************************************************************************************************************************************/
    /* <<<mouseMoved method to get location of mouse>>> */
    /*****************************************************************************************************************************************/
    @Override
    public void mouseMoved(MouseEvent me) {
        x_Cur = me.getX() - 20;
        y_Cur = me.getY() - 40;
    }// mouseMoved ends

    @Override
    public void mouseClicked(MouseEvent me) {
        start = 1;
        repaint();
    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
    }

    @Override
    public void mouseExited(MouseEvent arg0) {
    }

    @Override
    public void mousePressed(MouseEvent arg0) {
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
    }
}// class ends

0 个答案:

没有答案