如何创建一个重新启动按钮,该按钮在游戏运行时显示在按钮的左上角?

时间:2019-01-14 03:33:51

标签: java swing jpanel jbutton

我们的重新启动按钮仅单独出现。运行游戏时,我们的两个坦克消失了。我们尚未对按钮的功能进行编码,我们只是想弄清楚如何使按钮显示在左下角

我们将代码移到了游戏对象类中,但它没有任何改变

这是我们的游戏对象类。该按钮在底部。

import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GameObject {

    // Every moving object in our game is a separate GameObject. However, since there are different types of moving objects (eg. players and
    // projectiles), each with their own variables and functions, we don't want to instantiate GameObjects (otherwise, we wouldn't be able
    // to distinguish between a player and a projectile). Instead, we want to create derived (also known as child) classes to implement the
    // separate functionality, and instantiate the derived/child classes instead. The purpose of this GameObject "parent" class is to
    // provide the derived/child classes with a set of useful functions for handling physics interactions (eg. collisions with the terrain
    // or the walls of the arena) between different GameObjects (eg. player/player, player/projectile, or even projectile/projectile). Note:
    // depending on the features you implement, you may not end up using all of the functions provided in this class.

    // Every GameObject contains its own velocity, position, size, and mass information (necessary for moving and handling physics
    // interactions). We store this information in the GameObject class instead of the derived/child classes because every type of
    // GameObject has the same set of velocity, position, size, and mass variables.

    public double vX; // Velocity in the x direction. Positive if moving right. Negative if moving left.
    public double vY; // Velocity in the y direction. Positive if moving down. Negative if moving up. Notice how it's flipped from the usual
                        // coordinate system in math!

    public double posX; // Position along the x direction. Ranges from 0 (left edge) to maximumX (see below).
    public double posY; // Position along the y direction. Ranges from 0 (top edge) to maximumY (see below).

    public int width; // Width of the bounding box of the GameObject.
    public int height; // Height of the bounding box of the GameObject.

    public int mass; // Used in realistic physics collision calculations. Ignore it if you don't want to implement that feature.
    public double radius; // Used for circular GameObjects only.

    public int maximumX; // Maximum x position for a GameObject, equal to the arena width subtracted by the game object's width.
    public int maximumY; // Maximum y position for a GameObject, equal to the arena height subtracted by the game object's height.



    // Constructor. All derived (ie. child) classes call this constructor in their own constructors. The resulting derived/child class
    // object can then call the other functions in this class.
    public GameObject(int arenaWidth, int arenaHeight, double vX, double vY, double posX, double posY, int width, int height, int mass) {
        this.vX = vX;
        this.vY = vY;
        this.posX = posX;
        this.posY = posY;
        this.width = width;
        this.height = height;
        this.mass = mass;
        this.maximumX = arenaWidth - width;
        this.maximumY = arenaHeight - height;

        radius = Math.min(width, height) / 2.0;
    }

    // Note: No need to change this function since we're going to override it in the the child classes.
    public boolean move(Map map, double translateX, double translateY) {
        return false;
    }

    // Check if the calling GameObject currently intersects with the obj GameObject.
    public boolean currentlyIntersects(GameObject obj) {
        return (posX + width >= obj.posX && posY + height >= obj.posY && obj.posX + obj.width >= posX && obj.posY + obj.height >= posY);
    }

    // Check if the calling GameObject will intersect with the obj GameObject, after both have moved according to their velocities. A note
    // of caution: what might go wrong if either player moves too fast?
    public boolean willIntersect(GameObject obj) {
        double nextX = posX + vX;
        double nextY = posY + vY;
        double nextObjX = obj.posX + obj.vX;
        double nextObjY = obj.posY + obj.vY;
        return (nextX + width >= nextObjX && nextY + height >= nextObjY && nextObjX + obj.width >= nextX && nextObjY + obj.height >= nextY);
    }

    // Clip the calling GameObject to within the arena's x bounds, if it has moved outside the arena along the x direction.
    public boolean xClip() {
        if (posX < 0) {
            posX = 0;
            return true;
        } else if (posX > maximumX) {
            posX = maximumX;
            return true;
        }
        return false;
    }

    // Clip the calling GameObject to within the arena's y bounds, if it has moved outside the arena along the y direction.
    public boolean yClip() {
        if (posY < 0) {
            posY = 0;
            return true;
        } else if (posY > maximumY) {
            posY = maximumY;
            return true;
        }
        return false;
    }

    // If the calling GameObject will move outside the arena along either direction (after moving according to its velocity), this function
    // tells you which of the four edges of the arena it hit. If the calling GameObject will stay within the bounds of the arena, this
    // function returns null.
    public Direction hitEdgeDirection() {
        if (posX + vX < 0) {
            return Direction.LEFT;
        } else if (posX + vX > maximumX) {
            return Direction.RIGHT;
        }

        if (posY + vY < 0) {
            return Direction.UP;
        } else if (posY + vY > maximumY) {
            return Direction.DOWN;
        } else {
            return null;
        }
    }

    // If the calling GameObject will intersect with the "other" GameObject (after both move according to their velocities), this function
    // tells you which of the four sides of the calling GameObject that the "other" GameObject hit. If the calling GameObject will not
    // intersect with the "other" GameObject, this function returns null. Note: this function is great for figuring out when and where two
    // rectangles intersect, but is it a good choice for handling circle/rectangle or circle/circle intersections?
    public Direction hitObjectDirection(GameObject other) {
        if (this.willIntersect(other)) {
            double dx = other.posX + other.width / 2.0 + other.vX - (posX + width / 2.0 + vX);
            double dy = other.posY + other.height / 2.0 + other.vY - (posY + height / 2.0 + vY);

            double theta = Math.acos(dx / (Math.sqrt(dx * dx + dy * dy)));
            double diagTheta = Math.atan2(height / 2.0, width / 2.0);

            if (theta <= diagTheta) {
                return Direction.RIGHT;
            } else if (theta <= Math.PI - diagTheta) {
                if (dy > 0) {
                    return Direction.DOWN;
                } else {
                    return Direction.UP;
                }
            } else {
                return Direction.LEFT;
            }
        } else {
            return null;
        }
    }

    // Change the calling GameObject's velocity (to simulate a "bouncing" effect) based on which direction it intersected another GameObject
    // or the edge of the arena. If the passed in direction is null, this function does nothing (why is this a good idea?). This function is
    // best used with the hitEdgeDirection and hitObjectDirection functions above.
    public void bounce(Direction d) {
        if (d == null) {
            return;
        }
        // Note: We probably should use a "switch" statement here instead. But for pedagogical purposes it's left as a simple if/else
        // conditional.
        if (d == Direction.UP) {
            vY = Math.abs(vY);
        } else if (d == Direction.DOWN) {
            vY = -Math.abs(vY);
        } else if (d == Direction.LEFT) {
            vX = Math.abs(vX);
        } else if (d == Direction.RIGHT) {
            vX = -Math.abs(vX);
        }
    }

    // TODO: (Challenge!) If you want to implement realistic sphere-sphere collisions that take into account the laws of physics, do so in
    // the function below.
    public boolean bounceWith(GameObject otherObj, Map map, long frames, double[] actualVelocities) {
        return false;
    }

    // Calculate the distance from (pointX, pointY)---perhaps representing the center of a circle---to the closest point on a rectangle
    // bounded by minX (left), maxX (right), minY (top), and maxY (bottom). If the point is inside the rectangle, this function returns 0.
    public double pointToRectSqrDist(double minX, double maxX, double minY, double maxY, double pointX, double pointY) {
        double dx = Math.max(Math.max(minX - pointX, 0), pointX - maxX);
        double dy = Math.max(Math.max(minY - pointY, 0), pointY - maxY);
        return dx * dx + dy * dy;
    }

    // Rotate the point (x, y) "degrees" degrees around (centerX, centerY) in counterclockwise fashion, and return the resulting point in an
    // array of length 2. If the returned array is "result", then (result[0], result[1]) is the final point.
    public double[] rotatePoint(double centerX, double centerY, double degrees, double x, double y) {
        double s = Math.sin(Math.toRadians(degrees));
        double c = Math.cos(Math.toRadians(degrees));
        x -= centerX;
        y -= centerY;
        double xNew = x * c - y * s;
        double yNew = x * s + y * c;
        double[] result = new double[2];
        result[0] = xNew + centerX;
        result[1] = yNew + centerY;
        return result;
    }

    // Note: No need to change this function since we're going to override it in the the child classes.
    public void draw(Graphics g) {

    }

    public static void main(String []args){
        JButton b= new JButton("Reset");
        JFrame f = new JFrame();
        f.setSize(1200,800);
        f.setVisible(true);
        f.getDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel p = new JPanel();
        f.add(p);
        p.add(b);
        b.setSize(50,50);
        b.setVisible(true);
        b.setLocation(50, 50);

    }
}

这是我们的竞技场课程:

// TODO: Feel free to import any other libraries that you need.
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;

@SuppressWarnings("serial")
public class Arena extends JPanel {
    public int arenaWidth;
    public int arenaHeight;

    public Player player1;
    public Player player2;

    Timer timer;
    public static int INTERVAL = 35;
    public long lastTick;

    // TODO: Add other variables to keep track of the game state or other game objects (eg. the map) that will be in your game. Don't forget
    // to instantiate them in reset()!

    // Constructor. Called inside Game.java for setting up the Arena on game start.
    public Arena() {
        // Create a timer that calls the tick() function every INTERVAL milliseconds. Every call of the tick() function is a "frame".
        timer = new Timer(INTERVAL, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tick();
            }
        });
        lastTick = System.currentTimeMillis();
        timer.start();

        setFocusable(true);

        // TODO: To recognize key presses, you need to fill in the following.
        addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent butthole) {
                if (butthole.getKeyCode() == KeyEvent.VK_W) {
                    player1.isWPressed = true;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_S) {
                    player1.isSPressed = true; 
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_A) {
                    player1.isAPressed = true;
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_D) {
                    player1.isDPressed = true;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_SPACE) {
                    player1.isSpacePressed = true;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_UP) {
                    player2.isUpPressed = true;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_DOWN) {
                    player2.isDownPressed = true; 
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_LEFT) {
                    player2.isLeftPressed = true;
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_RIGHT) {
                    player2.isRightPressed = true;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_ENTER) {
                    player2.isEnterPressed = true;

        }
    }

            public void keyReleased(KeyEvent butthole) {
                if (butthole.getKeyCode() == KeyEvent.VK_W) {
                    player1.isWPressed = false;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_S) {
                    player1.isSPressed = false; 
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_A) {
                    player1.isAPressed = false;
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_D) {
                    player1.isDPressed = false;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_SPACE) {
                    player1.isSpacePressed = false;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_UP) {
                    player2.isUpPressed = false;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_DOWN) {
                    player2.isDownPressed = false; 
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_LEFT) {
                    player2.isLeftPressed = false;
                } 
                if (butthole.getKeyCode() == KeyEvent.VK_RIGHT) {
                    player2.isRightPressed = false;
                }
                if (butthole.getKeyCode() == KeyEvent.VK_ENTER) {
                    player2.isEnterPressed = false;

        }
    }

        });
    }

    // Resets the game to its initial state.
    public void reset() {
        this.removeAll();
        this.setBackground(Color.WHITE);
        this.setOpaque(true);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        arenaWidth = (int) screenSize.getWidth();
        arenaHeight = (int) screenSize.getHeight();

        player1 = new Player(arenaWidth, arenaHeight, 100, 100, 1);
        player2 = new Player(arenaWidth, arenaHeight, arenaWidth - Player.INIT_SIZE - 100, arenaHeight - Player.INIT_SIZE - 100, 2);

        requestFocusInWindow();
    }

    // Function called once per "frame".
    void tick() {
        // While tick() should be called once every INTERVAL amount of time, there's no guarantee of that, particularly if you have a lot
        // of background apps running. Thus, we need to calculate the time difference (timeDelta) between every two calls of the tick()
        // function. Note: 1 divided by this difference is commonly known as the "frames per second", or fps.
        long currentTime = System.currentTimeMillis();
        long timeDelta = (currentTime - lastTick)/35;
        lastTick = currentTime; 

        if ((player1.isWPressed && player1.isSPressed) ||
        (!player1.isWPressed && !player1.isSPressed)) {
            player1.vX = 0;
            player1.vY = 0;
        } else if (player1.isWPressed) {
            //System.out.println("Up");
            player1.vX = Math.cos(player1.RotationDegree*Math.PI/180)*player1.speed * timeDelta;
            player1.vY = Math.sin(player1.RotationDegree*Math.PI/180)*player1.speed * timeDelta;
            //player1.posY -= player1.speed*timeDelta;
            // MOVE FORWARD
        } else if (player1.isSPressed) {
            //System.out.println("Down");
            player1.vX = -Math.cos(player1.RotationDegree*Math.PI/180)*player1.speed * timeDelta;
            player1.vY = -Math.sin(player1.RotationDegree*Math.PI/180)*player1.speed * timeDelta;
            //player1.posY += player1.speed*timeDelta;
            // MOVE BACKWARD;
        }   
        if (player1.isAPressed) {
            //System.out.println("Left");
            player1.RotationDegree -= player1.rotateSpeed* timeDelta;
            // MOVE BACKWARD;
        }
        if (player1.isDPressed) {
            //System.out.parintln("Right");
            player1.RotationDegree += player1.rotateSpeed* timeDelta;
            // MOVE BACKWARD;
        }
        if(player1.RotationDegree > 360) {
            player1.RotationDegree -= 360;
        }
        else if(player1.RotationDegree < 0) {
            player1.RotationDegree += 360;


        } 
        player1.move(null, player1.vX, player1.vY);

        if ((player2.isUpPressed && player2.isDownPressed) ||
        (!player2.isUpPressed && !player2.isDownPressed)) {
         player2.vX = 0;
         player2.vY = 0; }
            else if (player2.isUpPressed) {
            //System.out.println("Up");
            player2.vX = Math.cos(player2.RotationDegree*Math.PI/180)*player2.speed* timeDelta;
            player2.vY = Math.sin(player2.RotationDegree*Math.PI/180)*player2.speed* timeDelta;
            //player2.posY -= player2.speed*timeDelta;
            // MOVE FORWARD
        }
        else if (player2.isDownPressed) {
            //System.out.println("Down");
            player2.vX = -Math.cos(player2.RotationDegree*Math.PI/180)*player2.speed * timeDelta;
            player2.vY = -Math.sin(player2.RotationDegree*Math.PI/180)*player2.speed * timeDelta;
            //player2.posY += player2.speed*timeDelta;
            // MOVE BACKWARD;
        }
        if (player2.isLeftPressed) {
            //System.out.println("Left");
            player2.RotationDegree -= player2.rotateSpeed*timeDelta;
            // MOVE BACKWARD;
        }
        if (player2.isRightPressed) {
            //System.out.println("Right");
            player2.RotationDegree += player2.rotateSpeed*timeDelta;
            // MOVE BACKWARD;
        }
        if(player2.RotationDegree > 360) {
            player2.RotationDegree -= 360;
        }
        else if(player2.RotationDegree < 0) {
            player2.RotationDegree += 360;
        }
            player2.move(null, player2.vX, player2.vY);

        player1.currentReload -= timeDelta;
        if (player1.currentReload <= 0)
            ;
        {
            if (player1.isSpacePressed) {
                // create bullet and fire
                BasicWeapon newBullet = new BasicWeapon(arenaWidth, arenaHeight, player1.posX + player1.radius, player1.posY + player1.radius, player1);
                player1.bullets.add(newBullet);
                player1.currentReload = player1.MaxReload;
            }
        }
        ArrayList<PlayerProjectile> bulletsToDelete1 = new ArrayList<PlayerProjectile>();
        for (int i = 0; i < player1.bullets.size(); i++) {
            PlayerProjectile bulletToChange = player1.bullets.get(i);

            bulletsToDelete1.add(bulletToChange);


        }

        player1.bullets.removeAll(bulletsToDelete1);


        // TODO: Update the game state each frame. This can be broken into the following steps:
        // Step 1: Handle the keys pressed during the last frame by both players and calculate their resulting velocities/orientations.
        // Step 2: Move the players and detect/handle player/player collisions and player/terrain collisions.
        // Step 3: Decide whether a bullet should be fired for each player and create new bullet(s) if so. Also, handle reload mechanics.
        // Step 4: Move all bullets via their calculated velocities (up to bullet range). Handle bullet/player & bullet/terrain collisions.
        // Step 5: Decide whether the game has ended. If so, stop the timer and print a message to the screen indicating who's the winner.
        // Note: If you implement other features (eg. weapon swapping, damage counters...etc.), you might also need to add more steps above.

        // Update the display: this function calls paintComponent as part of its execution.
        repaint(); }


    // TODO: Draw all of the objects in your game.
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        //AffineTransform at = AffineTransoform.getTranslateInstance();

        player1.draw(g);
        player2.draw(g);

    }

    // Returns the dimensions of the Arena (for properly resizing the JPanel on the screen).
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(arenaWidth, arenaHeight);
    }
}

THIS IS OUR PLAYER CLASS


// TODO: Feel free to import any other libraries that you need.
//import java.*;
import java.awt.*;
import java.util.ArrayList;
//import javax.swing.*;
//import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Player extends GameObject {
    public static void main(String []args){


    }

    // TODO: Set these values as you see fit. However, which variables should you not set as negative numbers? Which variables should you
    // not set as zero? Which v'ariables should you not set as a very large positive number? Why?
    public static final int INIT_SIZE = 30;
    public static final int INIT_MASS = 0;

    public static final int INIT_DAMAGE = 0;
    public static final double INIT_SPEED = 10;
    public static final double INIT_ROTATE_SPEED = 10;
    public static final int INIT_HEALTH = 100;

    // Member variables of the player that you can change over the course of the game.
    public int damage = INIT_DAMAGE;
    public double speed = INIT_SPEED;
    public double rotateSpeed = INIT_ROTATE_SPEED;
    public int health = INIT_HEALTH;
    public double orientation = 0;
    public int id;

    // TODO: You may need to set up extra variables to store the projectiles fired by this player, the reload status/time of this player,
    // the key press/release status of this player, and any other player-related features you decide to implement. Make sure to update the
    // constructor appropriately as well!

    long currentReload = 0;
    long MaxReload =  BasicWeapon.INIT_RELOAD;

    ArrayList<PlayerProjectile> bullets = new ArrayList<PlayerProjectile>();

    double RotationDegree = 0;
    boolean isWPressed = false;
    boolean isSPressed = false;
    boolean isAPressed = false;
    boolean isDPressed = false;
    boolean isSpacePressed = false;
    boolean isEnterPressed = false;
    boolean isUpPressed = false;
    boolean isDownPressed = false;
    boolean isLeftPressed = false;
    boolean isRightPressed = false;
    boolean isLeftCLickPressed = false;


    // Constructor that calls the super (ie. parent) class's constructor and instantiates any other player-specific variables.
    public Player(int arenaWidth, int arenaHeight, double startPosX, double startPosY, int id) {
        super(arenaWidth, arenaHeight, 0, 0, startPosX, startPosY, INIT_SIZE, INIT_SIZE, INIT_MASS);
        this.id = id;
    }

    // TODO: This function should move the player and handle any player-terrain interactions.
    @Override
    public boolean move(Map map, double translateX, double translateY) {
        posX += translateX;
        posY += translateY;
        xClip();
        yClip();

        return false;
    }
        //UPDATE PLAYER POSTION HERE
    //}

    public void draw(Graphics g) {
        // TODO: Draw the barrel(s) for the player here
        double xChords[] = new double[4];
        double YChords[] = new double[4];

        xChords[0] = posX + 0.6 * width;
        xChords[1] = posX + 0.6 * width;
        xChords[2] = posX + 1.5 * width;
        xChords[3] = posX + 1.5 * width;

        YChords[0] = posY + 0.4 * height;
        YChords[1] = posY + 0.5 * height;
        YChords[2] = posY + 0.5 * height;
        YChords[3] = posY + 0.4 * height;

        double[] point0 = rotatePoint(posX + 0.5 * width, posY + 0.5 * height, RotationDegree, xChords[0], YChords[0]);
        double[] point1 = rotatePoint(posX + 0.5 * width, posY + 0.5 * height, RotationDegree, xChords[1], YChords[1]);
        double[] point2 = rotatePoint(posX + 0.5 * width, posY + 0.5 * height, RotationDegree, xChords[2], YChords[2]);
        double[] point3 = rotatePoint(posX + 0.5 * width, posY + 0.5 * height, RotationDegree, xChords[3], YChords[3]);

        int rotatedPointsX[] = new int[4];
        int rotatedPointsY[] = new int[4];

        rotatedPointsX[0] = (int)Math.round(point0[0]);
        rotatedPointsX[1] = (int)Math.round(point1[0]);
        rotatedPointsX[2] = (int)Math.round(point2[0]);
        rotatedPointsX[3] = (int)Math.round(point3[0]);

        rotatedPointsY[0] = (int)Math.round(point0[1]);
        rotatedPointsY[1] = (int)Math.round(point1[1]);
        rotatedPointsY[2] = (int)Math.round(point2[1]);
        rotatedPointsY[3] = (int)Math.round(point3[1]);

        g.drawPolygon(rotatedPointsX, rotatedPointsY, 4);
        g.setColor(Color.BLACK);
        g.fillPolygon(rotatedPointsX, rotatedPointsY, 4);



        if (id == 1) {
            g.setColor(new Color(255, 215, 0));
        } else if (id == 2) {
            g.setColor(Color.RED);
        }
        // Body
        g.fillOval((int) posX, (int) posY, width, height);
        g.setColor(Color.BLACK);
        g.drawOval((int) posX, (int) posY, width, height);

        // TODO: Draw the health bar for the player here.



    }
}

仅显示按钮,而player1player2则不显示。

1 个答案:

答案 0 :(得分:1)

我认为您想要实现的目标是:

Promise.resolve

对于以后的问题,请不要发布太多代码。参见:don't just copy in your entire program!