2

私はちょうど Java が上手になるためにゲームをプログラミングしています。プレイヤーのローテーションを正しく機能させるのに苦労していました。私の最初の方法はこれを使用しました

g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos + (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));

ただし、これによりすべての画像がプレイヤーとともに回転し、射撃と照準が完全に機能しなくなりました。私は調査していて、誰かがこのコードを使用してプレーヤーを回転させるのを見ました。

    Graphics2D g2 = (Graphics2D)g;
           AffineTransform oldTransform = g2.getTransform();
    AffineTransform newOne = (AffineTransform)(oldTransform.clone());
    newOne.rotate(radAngle,x_pos + (img.getWidth() / 2),y_pos+ (img.getHeight()  / 2));
    g2.setTransform(newOne);
    g2.drawImage(img, x_pos,y_pos,this);
    repaint();
    g2.setTransform(oldTransform);

これはうまく機能し、以前と同じ問題はありません。しかし、私は理由を知りません。

これが私の完全なコードです。上記のコードは、ペイント メソッドの本体用です。

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.lang.Math.*;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.imageio.ImageIO;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;

public class Game extends Applet implements Runnable, KeyListener, MouseMotionListener, MouseListener
{
//pos variables keep track of the current position of the player
int x_pos = 250;
int y_pos = 250;
//speed variables keep track of the speed/how many pixels will be added to position during this iteration of the thread
float x_speed = 0;
float y_speed = 0;
int radius = 25;
//denotes the boundries of the applet
int appletsize_x = 800;
int appletsize_y = 600;
//the x and y variables mark whether a movement key is being pressed thats telling the object to move on
//on of those axes's
int x = 0;
int y = 0;
//variables that will indicate whether one of those keys are being depressed
int up = 0;
int down= 0;
int left = 0;
int right= 0;

int mouse_x;
int mouse_y;
int tracking_angle;
//getting some images.
private BufferedImage dbImage;
private BufferedImage test;
private Graphics dbg;
private  Image curser;
BufferedImage img = null;
BufferedImage round = null;
   double x_dist;
    double y_dist;



//i dont use this AffineTransform, although ill leave it here just incase i decide to use it if i continue working
//on this independently.
AffineTransform at = new AffineTransform();
//the angle of the mouse to the player object.
double radAngle;
public void init()
{


        try {
           URL url = new URL(getCodeBase(), "UFO.png");
           img = ImageIO.read(url);
        } catch (IOException e) {System.out.println("Cant find player image");
    }
                    try {
                       URL url = new URL(getCodeBase(), "round.png");
                       round = ImageIO.read(url);}
         catch (IOException e) {System.out.println("round not loading");}

    setBackground (Color.black);
    setFocusable(true);
    addKeyListener( this );
    curser = getImage(getDocumentBase(), "mouse.png");
    addMouseMotionListener(this);
    addMouseListener(this);
    try
    //changing the curser to the  crosshair image
            {
                Toolkit tk = Toolkit.getDefaultToolkit();
                Cursor c = tk.createCustomCursor( curser,new Point( 5, 5 ), "Cross_Hair" );
                setCursor( c );
            }
            catch( IndexOutOfBoundsException x )
            {System.out.println("Cross_hair");}
}

public class Shot {
    final double angle = radAngle;
    double x_loc;
    double  y_loc;
    double X;
    double Y;

    public Shot(){
        x_loc += x_pos;
        y_loc += y_pos;
        X=Math.cos(radAngle)*5;
        Y=Math.sin(radAngle)*5;
    }

    public void move(){

    x_loc += X;
    y_loc += Y;}
            }
//start the thread
public void start ()
{

    Thread th = new Thread (this);

    th.start ();

}

public void stop()
{

}

public void destroy()
{

}
//cathces the mouseEvent when the mosue is moved.
public void mouseClicked(MouseEvent e){}
public void mousePressed(MouseEvent e){
Shot shoot = new Shot();
shots.add(shoot);}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseMoved(MouseEvent e){
    //get position of mouse
    mouse_x = e.getX();
    mouse_y = e.getY();
    //get the distence from the player to the

    //i calculate the actual angle of the mosue from the player object in radians




    //this exists more just for debugging purposes since radians make no sense to me
    tracking_angle = 90;

    }
public void mouseDragged(MouseEvent e){
    mouse_x = e.getX();
    mouse_y = e.getY();
    Shot shoot = new Shot();
    shots.add(shoot);}

//this method sets the key variables to zero when the keys are released
public void keyReleased(KeyEvent r)
{
    //Right
    if (r.getKeyCode()  == 68 ){
        x = 0;
        left = 0;

        }
    //Left
    if (r.getKeyCode() == 65){
        x = 0;
        right = 0;
        }
    //Up
    if (r.getKeyCode() == 87 ) {
        //y_speed = 0;
        down = 0;}
    //Down
    if (r.getKeyCode() == 83 ) {
        //y_speed = 0;
        up = 0;}
        //move();
}
public void keyTyped(KeyEvent t){}
//changes the variables when a key is pressed so that the player object will move
public void keyPressed(KeyEvent r){


    //right
    if (r.getKeyCode()  == 68 ){
        left = 1;
        }
    //left
    if (r.getKeyCode() == 65){
        right = 1;}
    //Down
    if (r.getKeyCode() == 87 ) {
        down = 1;}
    //Up
    if (r.getKeyCode() == 83) {
        up = 1;}
        //move();
}

//sorta like the body of the thread i think
public void run ()
{


    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);


    while (true)
    {
        System.out.println(Math.tan(radAngle)/1);
        x_dist = mouse_x - x_pos;
        y_dist = mouse_y - y_pos;

        radAngle = Math.atan2(y_dist , x_dist);
        //if(tracking_angle < 0){
            //tracking_angle = absT
        if (left  == 1 && x_speed < 11){
            x = 0;
            x_speed += 1;
            }
        //Right
        if (right == 1 && x_speed > -11){
            x = 0;
             x_speed -= 1;
            }
        //Down
        if (down == 1  && y_speed > -11) {
            y_speed -= 1;}
        //Up
        if (up == 1  && y_speed < 11) {
        y_speed += 1;}
    if( x == 0 && x_speed > 0){
        x_speed -=.2;}
    if( x == 0 && x_speed < 0){
        x_speed +=.2;}
    if( y == 0 && y_speed > 0){
        y_speed -=.2;}
    if( y == 0 && y_speed < 0){
        y_speed +=.2;}



        if (x_pos > appletsize_x - radius && x_speed > 0)
        {

            x_pos = radius;
        }

        else if (x_pos < radius && x_speed < 0)
        {

            x_pos = appletsize_x + radius ;
        }

        if (y_pos > appletsize_y - radius && y_speed > 0){
            y_speed = 0;}
        else if ( y_pos < radius && y_speed < 0  ){
                y_speed = 0;}

        x_pos += (int)x_speed;
        y_pos += (int)y_speed;


        repaint();

        try
        {

            //tells the thread to wait 15 milliseconds util it executes again.
            Thread.sleep (15);


        }
        catch (InterruptedException ex)
        {

        }


        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    }
}


public void update (Graphics g)
{

    if (dbImage == null)
    {
        dbImage = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_RGB);
        dbg = dbImage.getGraphics ();
    }


    dbg.setColor (getBackground ());
    dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);


    dbg.setColor (getForeground());
    paint (dbg);
    shot_draw(dbg);


    g.drawImage (dbImage, 0, 0, this);



}

ArrayList<Shot> shots = new ArrayList<Shot>();
double last_angle = 1000;

public void paint (Graphics g){

    Graphics2D g2 = (Graphics2D)g;
    AffineTransform oldTransform = g2.getTransform();
    AffineTransform newOne = (AffineTransform)(oldTransform.clone());
    newOne.rotate(radAngle,x_pos + (img.getWidth() / 2),y_pos+(img.getHeight() / 2));
    g2.setTransform(newOne);
    g2.drawImage(img, x_pos,y_pos,this);
    repaint();
    g2.setTransform(oldTransform);
   // g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos +   (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));
    //g2.getTransform().setToIdentity();


}
public void shot_draw(Graphics g){

    Graphics2D g2 = (Graphics2D)g;
//        Shot shoot = new Shot();
//        shots.add(shoot);
    for(Shot i: shots){
        g2.drawImage(round,(int)i.x_loc+40,(int)i.y_loc+40,this);
        i.move();}


        }}

ここに私が使用している画像があります:

4

2 に答える 2

1

Graphics オブジェクトの AffineTransform をベースラインにリセットしないと、新しい変換を使用してすべての画像を含むすべてが描画されるため、これは理にかなっています。repaint()ただし、メソッド内から from を呼び出す理由がわかりませんpaint。これを行うべきではありません。

于 2011-07-31T02:50:11.393 に答える
1

オブジェクトは、への呼び出しを介してオブジェクトAffineTransformに接続されます。接続されると、そのオブジェクトを使用して描画されたすべてのオブジェクトが、への別の呼び出しによって新しいオブジェクトに割り当てられるまで、同じ変換 (この場合は回転) が適用されて描画されます。あなたが見つけたサンプルコードは、古い変換を保存しました(おそらく、通常の非回転状態をエンコードします)Graphics2DsetTransformGraphics2DAffineTransformGraphics2DsetTransform

AffineTransform oldTransform = g2.getTransform();

次に、コードは回転変換を作成し、それを に接続しGraphics2D(これで、描画されるすべてのオブジェクトは、新しい変換が割り当てられるまで回転します)、回転して描画する必要がある 1 つのオブジェクトを描画しました (したがって、新しく作成された回転変換が適用されました)。それに)、元の非回転変換を次の方法で Graphics2D オブジェクトに復元します

g2.setTransform(oldTransform);

そうすれば、後続のオブジェクトに適用される変換は、元の非回転変換になります。

于 2011-07-31T05:35:54.707 に答える