图形未出现在 JFrame 中(包括 SSCCE)

发布于 2024-11-14 01:42:59 字数 16894 浏览 3 评论 0原文

我正在制作一款游戏(请参阅我之前的帖子),并且在制作过程中遇到了很多问题。我所知道的是他的代码编译、运行,但窗口中没有出现任何内容,它只是灰色的。根据安德鲁·汤普森的建议,我在这里发布了完整的可编译版本。抱歉,篇幅较长,但这是程序中的所有代码。很多事情可能没有意义(例如未使用的 ActionPerformed),部分是因为我在需要时实现了代码,但主要是因为我以前从未这样做过。

另外,到目前为止我还没有多线程,因为我再次对此感到陌生,所以理想情况下我希望保持这种状态,即使只是为了我的理智。

编辑:忘记提及我有 4 个 PNG,代表出现的 4 个不同对象。我的代码足够灵活,您可以提供自己的代码。这是我用于船舶的图像 在此处输入图像描述 这是子弹的图像 在此处输入图像描述 只需复制一份,将它们放入源文件并命名为“Enemy-ship”“ship2”“Ebullet”和“PBullet”

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

import javax.swing.JFrame;


public class GameController extends JFrame implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = -3599196025204169130L;
    private static GameView window;
    private static Timer time;

    public GameController()
    {
        setTitle("Space Shooter");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 600);

        //window = new GameView(800,600);
        //window.setVisible(true);

        //
    }
    //TODO spawn
    /*public static void main(String args[])
    {
        //GameController c = new GameController();
        window = new GameView(800,600);
        window.setVisible(true);

        time = new Timer(40, this);
        time.schedule( new TimerTask(){
            public void run(){GameState.update(); 
            window.paintComponents(null);}
            },0, 40);

    }*/




    public void display() {
        add(new GameView(800,600));
        pack();        
        setMinimumSize(getSize());// enforces the minimum size of both frame and component
        setVisible(true);
    }

    public static void main(String[] args) {
        GameController main = new GameController();
        main.display();
        time = new Timer(40, main);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if(e instanceof EndEvent)//TODO fix this
        {

        }
        else
        {
            repaint();
        }

    }
}



package Game;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class GameView extends JComponent implements ActionListener{

    /**
     * 
     */
    private static final long serialVersionUID = -2869672245901003704L;
    private static final Graphics Graphics = null;
    private boolean liveGame;//used so that buttons cannot be clicked after game is complete
    private GameState gs;
    private Player p;
    private int w, h;

    public GameView(int width, int height)
    {
        liveGame = true;
        gs = new GameState();
        GameState.init(width, height);
        p = new Player(width/2,(height*7)/8);
        this.setBackground(Color.BLACK);
        paintComponents(Graphics);
        w = width;
        h = height;
    }
       @Override
        public Dimension getMinimumSize() {
            return new Dimension(w, h);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(w, h);
        }

        @Override
        public void paintComponent(Graphics g) {
            int margin = 10;
            Dimension dim = getSize();
            super.paintComponent(g);
            g.setColor(Color.black);
            GameState.update();

            for(Bullet j : GameState.getEnBullets()){
                g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
            for(Enemy j : GameState.getEnemies()){
                g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
            for(Bullet j : GameState.getPlayBullets()){
                g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
            g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
        }

    public void paintComponents (Graphics g)
    {

        for(Bullet j : GameState.getEnBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Enemy j : GameState.getEnemies()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Bullet j : GameState.getPlayBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        this.paint(g);
    }



    public void refreshImage()
    {
        this.removeAll();
        paintComponents(Graphics);
    }


    public void actionPerformed(ActionEvent e) {


    }


}


package Game;
import java.awt.event.ActionEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
public class GameState {

    private static ArrayList<Bullet> playBullets;
    public static ArrayList<Bullet> getPlayBullets() {
        return playBullets;
    }

    public static ArrayList<Bullet> getEnBullets() {
        return enBullets;
    }

    public static ArrayList<Enemy> getEnemies() {
        return enemies;
    }

    public static Player getP() {
        return p;
    }

    private static ArrayList<Bullet> enBullets;
    private static ArrayList<Enemy> enemies;
    private static int X, Y;//for limit of screen so nothing can go outside of screen
    private static Player p;
    private static int score;

    public GameState(){

    }

    public static void init(int x, int y)
    {
        playBullets = new ArrayList<Bullet>();
        enBullets = new ArrayList<Bullet>();
        enemies = new ArrayList<Enemy>();
        X=x;
        Y=y;
        p = null;
        score =0;
    }

    public static int xLimit(){return X;}
    public static int yLimit(){return Y;}

    public static int getScore(){return score;}

    public static void add (Location e)
    {
        if(e instanceof Bullet)
        {
            if(((Bullet) e).getOwner() instanceof Enemy){
                enBullets.add((Bullet) e);
            }
            else
                playBullets.add((Bullet) e);
        }
        else if(e instanceof Enemy){enemies.add((Enemy)e);}
        else
            p=(Player)e;
    }

    public static void spawn()
    {
        Enemy e = new Enemy(((int)(Math.random()*(X-56))+28), 0, 1);
    }


    public static void playerCD()//detects  if player has collided with anything, removes whatever collided with it, and causes the player to take damage
    {
        if(enemies.size()>0){
        for(int i =0; i < enemies.size(); i++)
        {
            if (p.getLocation().intersects(enemies.get(i).getLocation()))
            {
                p.takeDamage(enemies.get(i).getDamage());
                enemies.get(i).takeDamage(p.getDamage());

            }
        }
        if(enBullets.size()>0)
        for(int i =0; i < enBullets.size(); i++)
        {
            if (p.getLocation().intersects(enBullets.get(i).getLocation()))
            {
                p.takeDamage(enBullets.get(i).getDamage());
                enBullets.remove(i);
                i--;

            }
        }
        }
    }

    public static void enemyCD()
    {
        for(int i =0; i < enemies.size(); i++)
        {
            for(int n =0; n < playBullets.size(); n++)
            {
                if (playBullets.get(n).getLocation().intersects(enemies.get(i).getLocation()))
                    {
                        enemies.get(i).takeDamage(playBullets.get(i).getDamage());
                        playBullets.remove(n);
                        n--;
                        score+=50;
                    }
                }
            }

        }

    public static void checkForDead()//clears away dead and things gone offscreen
    {

        for(int i =0; i < enemies.size(); i++)
        {
            if(enemies.get(i).getY()>Y)
            {
                enemies.remove(i);
                i--;
            }
        }


        for(int i =0; i < enBullets.size(); i++)
        {
            if(enBullets.get(i).getY()>Y)
            {
                enBullets.remove(i);
                i--;
            }
        }

        for(int i =0; i < enemies.size(); i++)
        {
            if(enemies.get(i).getHealth()>0)
            {
                enemies.remove(i);
                i--;
                score+=200;
            }
        }

        if(p.getHealth()<=0)
        {
            ActionEvent e = new EndEvent(null, 0, "end");
        }
    }

    public static void update()
    {
        move();
        playerCD();
        enemyCD();
        checkForDead();
    }

    public static void move()
    {
        p.move();
        for(int i =0; i < enemies.size(); i++){enemies.get(i).move();}
        for(int i =0; i < enBullets.size(); i++){enBullets.get(i).move();}
        for(int i =0; i < playBullets.size(); i++){playBullets.get(i).move();}
    }





}


package Game;

import java.awt.Rectangle;
import java.awt.event.ActionListener;

public abstract class Fights extends Location implements ActionListener {

    public Fights(Rectangle location) {
        super(location);
        // TODO Auto-generated constructor stub
    }

    public Fights(){}
    protected int health;
    protected int maxHealth;//in the event that I want to have healing items
    protected int shotCooldown;//in milliseconds
    protected int shotDmg;
    protected long currentCool; //cooldown tracker, represents time that shot will be cooled down by (System time @ last shot + shotCooldown
    protected int xVel, yVel;
    public abstract boolean shoot();
    public abstract int takeDamage(int damage);//returns remaining health
    protected boolean shoots;//determines whether thing can shoot. possible implementation in some enemy class
    public boolean move;
    public int getHealth(){return health;}
    public abstract boolean move();
    public int getDamage(){return shotDmg;}
    public boolean isDead()
    {
        return health<=0;
    }


}



package Game;

import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;



public class Location {
    protected Rectangle loc;
    protected Image image;

    public Location(){};

    public Location (Rectangle location)
    {
        loc = location;
    }

    public Rectangle getLocation()
    {
        return loc;
    }

    public void setLocation(Rectangle l)
    {
        loc = l;
    }

    public void updateLocation(int x, int y)
    {
        loc.setLocation(x, y);
    }

    public Image getImage()
    {
        return image;
    }

    public int getX()
    {
        return (int)loc.getX();
    }

    public int getY()
    {
        return (int)loc.getY();
    }
        }

package Game;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Player extends Fights implements KeyListener{

    int speed = 4;

    public Player(Rectangle location) {
        super(location);
        GameState.add(this);
        image = null;
        try{
            image = ImageIO.read(new File("ship2.png"));
        }catch(IOException e){}
    }

    public Player(int x, int y) {

        maxHealth = 1;
        health = maxHealth;
        image = null;
        try{
            image = ImageIO.read(new File("ship2.png"));
        }catch(IOException e){}


        this.setLocation(new Rectangle(x, y, image.getWidth(null), image.getHeight(null)));
        GameState.add(this);
    }

    public void resetVelocity()
    {
        xVel = 0;
        yVel = 0;
    }


    @Override
    public boolean shoot() {
        if(currentCool - System.currentTimeMillis() >0){return false;}
        else
        {
            new Bullet(this);
            currentCool = System.currentTimeMillis() + shotCooldown;
        }//spawns bullet in the center and slightly in front of player
        return true;
    }

    @Override
    public int takeDamage(int damage) {

        return health-=damage;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean move() {//moves in a direction only if it won't exceed screen boundary, boolean just in case i need it later
        int newX = this.getX(), newY=this.getY();
        if((xVel+ this.getX()+this.getLocation().width)<GameState.xLimit()&& this.getX()+xVel>=0)
        {
            newX +=xVel;
        }
        if((yVel+ this.getY()+this.getLocation().height)<GameState.yLimit()&& this.getY()+yVel>=0)
        {
            newY +=yVel;
        }
        this.updateLocation(newX, newY);
        this.resetVelocity();

        return true;
    }

    @Override
    public void keyPressed(KeyEvent arg0) {

        if (arg0.getKeyCode()== KeyEvent.VK_LEFT)
        {
            xVel -= speed;
        }


        if (arg0.getKeyCode()== KeyEvent.VK_RIGHT)
        {
            xVel += speed;
        }

        if (arg0.getKeyCode()== KeyEvent.VK_UP)
        {
            yVel -= speed;
        }


        if (arg0.getKeyCode()== KeyEvent.VK_DOWN)
        {
            yVel += speed;
        }

        if(arg0.getKeyCode()==KeyEvent.VK_SPACE)
        {
            this.shoot();
        }


    }

    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

}


package Game;

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Enemy extends Fights {

    public Enemy(Rectangle location) {
        super(location);
        GameState.add(this);
        image = null;
        try{
            image = ImageIO.read(new File("Enemy-Ship.png"));
        }catch(IOException e){}
    }
    public Enemy(int x, int y, int d) {
        image = null;
        try{
            image = ImageIO.read(new File("Enemy-Ship.png"));
        }catch(IOException e){}


        this.setLocation(new Rectangle(x, y, image.getWidth(null), image.getHeight(null)));
        GameState.add(this);

        shotCooldown =(int)(Math.random()*2000);

        xVel = (int)((Math.pow(-1, (int)(Math.random())))*((int)(Math.random()*6))+2);
        yVel = (int)(Math.random()*3+1);
        shotDmg =d;
    }


    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean shoot() {
        if(currentCool - System.currentTimeMillis() >0){return false;}
        else
        {
            new Bullet(this);
            currentCool = System.currentTimeMillis() + shotCooldown;
        }//spawns bullet in the center and slightly in front of player
        return true;
    }

    @Override
    public int takeDamage(int damage)//returns remaining health
    {
        health = health-damage;
        return health;
    }
    @Override
    public boolean move() {
        int newX = this.getX(), newY=this.getY();
        if((xVel+ this.getX()+this.getLocation().width)<GameState.xLimit()&& this.getX()+xVel>=0)
        {
            xVel=-xVel;
            newX +=xVel;
        }
        if(this.getY()+yVel>=0)
        {
            newY +=yVel;
        }
        this.updateLocation(newX, newY);

        return true;
    }

}

package Game;

import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Bullet extends Location{
    private Fights bulletOwner;
    private int damage;
    private int velocity;

    public Bullet(Fights owner)//eventually change to singleton pattern for efficiency
    {
        bulletOwner = owner;
        damage = owner.getDamage();
        image = null;
        if(owner instanceof Enemy)
        {
            try{
                image = ImageIO.read(new File("Ebullet.png"));
            }catch(IOException e){}
            this.setLocation(new Rectangle(owner.getX(), owner.getY()+((int)(owner.getLocation().getHeight()/2)), image.getWidth(null), image.getHeight(null)));
            velocity = 5;

        }

        else
        {
            try{
                image = ImageIO.read(new File("Pbullet.png"));
            }catch(IOException e){}
            this.setLocation(new Rectangle(owner.getX(), owner.getY()-((int)(owner.getLocation().getHeight()/2)), image.getWidth(null), image.getHeight(null)));
            velocity = -15;

        }
        GameState.add(this);


    }

    public Fights getOwner(){return bulletOwner;}
    public int getDamage(){return damage;}
    public int getVelocity(){return velocity;}
    public boolean move()
    {
        this.updateLocation(this.getX(), this.getY()+velocity);
        return true;
    }


}

I am making a game (see my previous threads) and have encountered a lot of problems on the way. All I know is that he code compiles, runs, but nothing appears in the window, it's just grey. At Andrew Thompson's suggestion, I am posting the entire compilable version here. Sorry for the length but it is ALL the code in the program. And a lot of things will probably not make sense (unused ActionPerformed to name one), partially because I implemented code in the event that I would need it but mostly because I have never done this before.

Also, so far I have no multithreading, because once again, I am new to this, so ideally I would like to keep it that way, if only for the sake of my sanity.

EDIT: Forgot to mention I have 4 PNGs in there representing the 4 different objects that appear. My code is flexible enough for you to supply your own. Here is the image I am using for ships enter image description here and here is the one for bullets enter image description here just make copies, put them the source file and name them "Enemy-ship" "ship2" "Ebullet" and "PBullet"

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

import javax.swing.JFrame;


public class GameController extends JFrame implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = -3599196025204169130L;
    private static GameView window;
    private static Timer time;

    public GameController()
    {
        setTitle("Space Shooter");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 600);

        //window = new GameView(800,600);
        //window.setVisible(true);

        //
    }
    //TODO spawn
    /*public static void main(String args[])
    {
        //GameController c = new GameController();
        window = new GameView(800,600);
        window.setVisible(true);

        time = new Timer(40, this);
        time.schedule( new TimerTask(){
            public void run(){GameState.update(); 
            window.paintComponents(null);}
            },0, 40);

    }*/




    public void display() {
        add(new GameView(800,600));
        pack();        
        setMinimumSize(getSize());// enforces the minimum size of both frame and component
        setVisible(true);
    }

    public static void main(String[] args) {
        GameController main = new GameController();
        main.display();
        time = new Timer(40, main);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if(e instanceof EndEvent)//TODO fix this
        {

        }
        else
        {
            repaint();
        }

    }
}



package Game;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class GameView extends JComponent implements ActionListener{

    /**
     * 
     */
    private static final long serialVersionUID = -2869672245901003704L;
    private static final Graphics Graphics = null;
    private boolean liveGame;//used so that buttons cannot be clicked after game is complete
    private GameState gs;
    private Player p;
    private int w, h;

    public GameView(int width, int height)
    {
        liveGame = true;
        gs = new GameState();
        GameState.init(width, height);
        p = new Player(width/2,(height*7)/8);
        this.setBackground(Color.BLACK);
        paintComponents(Graphics);
        w = width;
        h = height;
    }
       @Override
        public Dimension getMinimumSize() {
            return new Dimension(w, h);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(w, h);
        }

        @Override
        public void paintComponent(Graphics g) {
            int margin = 10;
            Dimension dim = getSize();
            super.paintComponent(g);
            g.setColor(Color.black);
            GameState.update();

            for(Bullet j : GameState.getEnBullets()){
                g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
            for(Enemy j : GameState.getEnemies()){
                g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
            for(Bullet j : GameState.getPlayBullets()){
                g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
            g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
        }

    public void paintComponents (Graphics g)
    {

        for(Bullet j : GameState.getEnBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Enemy j : GameState.getEnemies()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Bullet j : GameState.getPlayBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        this.paint(g);
    }



    public void refreshImage()
    {
        this.removeAll();
        paintComponents(Graphics);
    }


    public void actionPerformed(ActionEvent e) {


    }


}


package Game;
import java.awt.event.ActionEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
public class GameState {

    private static ArrayList<Bullet> playBullets;
    public static ArrayList<Bullet> getPlayBullets() {
        return playBullets;
    }

    public static ArrayList<Bullet> getEnBullets() {
        return enBullets;
    }

    public static ArrayList<Enemy> getEnemies() {
        return enemies;
    }

    public static Player getP() {
        return p;
    }

    private static ArrayList<Bullet> enBullets;
    private static ArrayList<Enemy> enemies;
    private static int X, Y;//for limit of screen so nothing can go outside of screen
    private static Player p;
    private static int score;

    public GameState(){

    }

    public static void init(int x, int y)
    {
        playBullets = new ArrayList<Bullet>();
        enBullets = new ArrayList<Bullet>();
        enemies = new ArrayList<Enemy>();
        X=x;
        Y=y;
        p = null;
        score =0;
    }

    public static int xLimit(){return X;}
    public static int yLimit(){return Y;}

    public static int getScore(){return score;}

    public static void add (Location e)
    {
        if(e instanceof Bullet)
        {
            if(((Bullet) e).getOwner() instanceof Enemy){
                enBullets.add((Bullet) e);
            }
            else
                playBullets.add((Bullet) e);
        }
        else if(e instanceof Enemy){enemies.add((Enemy)e);}
        else
            p=(Player)e;
    }

    public static void spawn()
    {
        Enemy e = new Enemy(((int)(Math.random()*(X-56))+28), 0, 1);
    }


    public static void playerCD()//detects  if player has collided with anything, removes whatever collided with it, and causes the player to take damage
    {
        if(enemies.size()>0){
        for(int i =0; i < enemies.size(); i++)
        {
            if (p.getLocation().intersects(enemies.get(i).getLocation()))
            {
                p.takeDamage(enemies.get(i).getDamage());
                enemies.get(i).takeDamage(p.getDamage());

            }
        }
        if(enBullets.size()>0)
        for(int i =0; i < enBullets.size(); i++)
        {
            if (p.getLocation().intersects(enBullets.get(i).getLocation()))
            {
                p.takeDamage(enBullets.get(i).getDamage());
                enBullets.remove(i);
                i--;

            }
        }
        }
    }

    public static void enemyCD()
    {
        for(int i =0; i < enemies.size(); i++)
        {
            for(int n =0; n < playBullets.size(); n++)
            {
                if (playBullets.get(n).getLocation().intersects(enemies.get(i).getLocation()))
                    {
                        enemies.get(i).takeDamage(playBullets.get(i).getDamage());
                        playBullets.remove(n);
                        n--;
                        score+=50;
                    }
                }
            }

        }

    public static void checkForDead()//clears away dead and things gone offscreen
    {

        for(int i =0; i < enemies.size(); i++)
        {
            if(enemies.get(i).getY()>Y)
            {
                enemies.remove(i);
                i--;
            }
        }


        for(int i =0; i < enBullets.size(); i++)
        {
            if(enBullets.get(i).getY()>Y)
            {
                enBullets.remove(i);
                i--;
            }
        }

        for(int i =0; i < enemies.size(); i++)
        {
            if(enemies.get(i).getHealth()>0)
            {
                enemies.remove(i);
                i--;
                score+=200;
            }
        }

        if(p.getHealth()<=0)
        {
            ActionEvent e = new EndEvent(null, 0, "end");
        }
    }

    public static void update()
    {
        move();
        playerCD();
        enemyCD();
        checkForDead();
    }

    public static void move()
    {
        p.move();
        for(int i =0; i < enemies.size(); i++){enemies.get(i).move();}
        for(int i =0; i < enBullets.size(); i++){enBullets.get(i).move();}
        for(int i =0; i < playBullets.size(); i++){playBullets.get(i).move();}
    }





}


package Game;

import java.awt.Rectangle;
import java.awt.event.ActionListener;

public abstract class Fights extends Location implements ActionListener {

    public Fights(Rectangle location) {
        super(location);
        // TODO Auto-generated constructor stub
    }

    public Fights(){}
    protected int health;
    protected int maxHealth;//in the event that I want to have healing items
    protected int shotCooldown;//in milliseconds
    protected int shotDmg;
    protected long currentCool; //cooldown tracker, represents time that shot will be cooled down by (System time @ last shot + shotCooldown
    protected int xVel, yVel;
    public abstract boolean shoot();
    public abstract int takeDamage(int damage);//returns remaining health
    protected boolean shoots;//determines whether thing can shoot. possible implementation in some enemy class
    public boolean move;
    public int getHealth(){return health;}
    public abstract boolean move();
    public int getDamage(){return shotDmg;}
    public boolean isDead()
    {
        return health<=0;
    }


}



package Game;

import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;



public class Location {
    protected Rectangle loc;
    protected Image image;

    public Location(){};

    public Location (Rectangle location)
    {
        loc = location;
    }

    public Rectangle getLocation()
    {
        return loc;
    }

    public void setLocation(Rectangle l)
    {
        loc = l;
    }

    public void updateLocation(int x, int y)
    {
        loc.setLocation(x, y);
    }

    public Image getImage()
    {
        return image;
    }

    public int getX()
    {
        return (int)loc.getX();
    }

    public int getY()
    {
        return (int)loc.getY();
    }
        }

package Game;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Player extends Fights implements KeyListener{

    int speed = 4;

    public Player(Rectangle location) {
        super(location);
        GameState.add(this);
        image = null;
        try{
            image = ImageIO.read(new File("ship2.png"));
        }catch(IOException e){}
    }

    public Player(int x, int y) {

        maxHealth = 1;
        health = maxHealth;
        image = null;
        try{
            image = ImageIO.read(new File("ship2.png"));
        }catch(IOException e){}


        this.setLocation(new Rectangle(x, y, image.getWidth(null), image.getHeight(null)));
        GameState.add(this);
    }

    public void resetVelocity()
    {
        xVel = 0;
        yVel = 0;
    }


    @Override
    public boolean shoot() {
        if(currentCool - System.currentTimeMillis() >0){return false;}
        else
        {
            new Bullet(this);
            currentCool = System.currentTimeMillis() + shotCooldown;
        }//spawns bullet in the center and slightly in front of player
        return true;
    }

    @Override
    public int takeDamage(int damage) {

        return health-=damage;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean move() {//moves in a direction only if it won't exceed screen boundary, boolean just in case i need it later
        int newX = this.getX(), newY=this.getY();
        if((xVel+ this.getX()+this.getLocation().width)<GameState.xLimit()&& this.getX()+xVel>=0)
        {
            newX +=xVel;
        }
        if((yVel+ this.getY()+this.getLocation().height)<GameState.yLimit()&& this.getY()+yVel>=0)
        {
            newY +=yVel;
        }
        this.updateLocation(newX, newY);
        this.resetVelocity();

        return true;
    }

    @Override
    public void keyPressed(KeyEvent arg0) {

        if (arg0.getKeyCode()== KeyEvent.VK_LEFT)
        {
            xVel -= speed;
        }


        if (arg0.getKeyCode()== KeyEvent.VK_RIGHT)
        {
            xVel += speed;
        }

        if (arg0.getKeyCode()== KeyEvent.VK_UP)
        {
            yVel -= speed;
        }


        if (arg0.getKeyCode()== KeyEvent.VK_DOWN)
        {
            yVel += speed;
        }

        if(arg0.getKeyCode()==KeyEvent.VK_SPACE)
        {
            this.shoot();
        }


    }

    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

}


package Game;

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Enemy extends Fights {

    public Enemy(Rectangle location) {
        super(location);
        GameState.add(this);
        image = null;
        try{
            image = ImageIO.read(new File("Enemy-Ship.png"));
        }catch(IOException e){}
    }
    public Enemy(int x, int y, int d) {
        image = null;
        try{
            image = ImageIO.read(new File("Enemy-Ship.png"));
        }catch(IOException e){}


        this.setLocation(new Rectangle(x, y, image.getWidth(null), image.getHeight(null)));
        GameState.add(this);

        shotCooldown =(int)(Math.random()*2000);

        xVel = (int)((Math.pow(-1, (int)(Math.random())))*((int)(Math.random()*6))+2);
        yVel = (int)(Math.random()*3+1);
        shotDmg =d;
    }


    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean shoot() {
        if(currentCool - System.currentTimeMillis() >0){return false;}
        else
        {
            new Bullet(this);
            currentCool = System.currentTimeMillis() + shotCooldown;
        }//spawns bullet in the center and slightly in front of player
        return true;
    }

    @Override
    public int takeDamage(int damage)//returns remaining health
    {
        health = health-damage;
        return health;
    }
    @Override
    public boolean move() {
        int newX = this.getX(), newY=this.getY();
        if((xVel+ this.getX()+this.getLocation().width)<GameState.xLimit()&& this.getX()+xVel>=0)
        {
            xVel=-xVel;
            newX +=xVel;
        }
        if(this.getY()+yVel>=0)
        {
            newY +=yVel;
        }
        this.updateLocation(newX, newY);

        return true;
    }

}

package Game;

import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Bullet extends Location{
    private Fights bulletOwner;
    private int damage;
    private int velocity;

    public Bullet(Fights owner)//eventually change to singleton pattern for efficiency
    {
        bulletOwner = owner;
        damage = owner.getDamage();
        image = null;
        if(owner instanceof Enemy)
        {
            try{
                image = ImageIO.read(new File("Ebullet.png"));
            }catch(IOException e){}
            this.setLocation(new Rectangle(owner.getX(), owner.getY()+((int)(owner.getLocation().getHeight()/2)), image.getWidth(null), image.getHeight(null)));
            velocity = 5;

        }

        else
        {
            try{
                image = ImageIO.read(new File("Pbullet.png"));
            }catch(IOException e){}
            this.setLocation(new Rectangle(owner.getX(), owner.getY()-((int)(owner.getLocation().getHeight()/2)), image.getWidth(null), image.getHeight(null)));
            velocity = -15;

        }
        GameState.add(this);


    }

    public Fights getOwner(){return bulletOwner;}
    public int getDamage(){return damage;}
    public int getVelocity(){return velocity;}
    public boolean move()
    {
        this.updateLocation(this.getX(), this.getY()+velocity);
        return true;
    }


}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

微凉徒眸意 2024-11-21 01:42:59

我不敢相信您在没有进行任何测试的情况下编写了 700 行代码。是时候回到起点并从简单的事情开始了。这就是 SSCCE 的全部意义所在。从绘制几个组件开始。一旦你开始工作,你就可以添加一些动作。一旦工作正常,您就可以添加碰撞逻辑。

我通过快速浏览注意到的唯一一件事是您重写了paintComponents()。无需在 pantComponent() 方法中完成自定义绘制。

如果你不能生产出更小尺寸的SSCCE,那么我只能祝你好运。

I can't believe your write 700 lines of code without doing any testing along the way. Its time you go back to the beginning and start with something simple. That is the whole point of a SSCCE. Start with painting a couple of compononents. Once you get that working you add some movement. Once that is working you add collision logic.

The only thing I noticed with a quick broswe is that you override paintComponents(). There is no need to do that custom painting is done in the pantComponent() method.

If you can't produce a smaller sized SSCCE, then all I can do is wish you good luck.

忘年祭陌 2024-11-21 01:42:59

好吧,我想我已经弄清楚了大部分内容。

你有几个问题。

首先,你应该只看到一个灰色的屏幕,中间有一个黑色矩形,因为你的子弹和敌人阵列中没有任何东西。这是我运行代码时得到的结果(删除对 endEvent 的引用后,因为它找不到它)。所以要解决这个问题,只要给它一些东西来画就可以了

。一旦你给它一些东西来画,第二个问题就很明显了。我手动输入一行代码来绘制播放器,为此我使用了我自己的 png。当您这样做时,它将无法编译并出现空指针异常。原因是因为在您的 GameView 类中,您将名为“graphics”的 Graphics 对象设置为 null,但随后您继续调用 PaintComponents(graphics)。如前所述,这只是之前编译过的,因为您从未真正绘制过任何东西。要解决此问题,您只需删除

public void paintComponents (Graphics g)
{

    for(Bullet j : GameState.getEnBullets()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    for(Enemy j : GameState.getEnemies()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    for(Bullet j : GameState.getPlayBullets()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    this.paint(g);

}

并让其上方重写的paintComponent(Graphics g)方法完成所有工作即可。此外,请使用 repaint(),而不是 PaintComponents(graphics) 调用。您还可以在构造函数中删除对 PaintComponents(graphics) 的第一次调用,因为默认情况下它将第一次绘制。如果您确实想使用自己的方法,那么您必须创建一个 Graphics 对象并将其传入。

最后,在重写的 PaintComponents(Graphics g) 方法中,最后一行是绘制巨大的黑框。这将覆盖您之前绘制的任何内容。因此,您应该将其作为第一行,并按顺序绘制其他所有内容,以便您想要位于顶部的内容应该最后绘制。我能够使用该类的以下代码显示我的测试图像。我不认为我改变了任何其他事情。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class GameView extends JComponent implements ActionListener{

/**
 * 
 */
private static final long serialVersionUID = -2869672245901003704L;
private boolean liveGame;//used so that buttons cannot be clicked after game is complete
private GameState gs;
private Player p;
private int w, h;

public GameView(int width, int height)
{
    liveGame = true;
    gs = new GameState();
    GameState.init(width, height);
    p = new Player(width/2,(height*7)/8);
    this.setBackground(Color.BLACK);
    w = width;
    h = height;
}
   @Override
    public Dimension getMinimumSize() {
        return new Dimension(w, h);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(w, h);
    }

    @Override
    public void paintComponent(Graphics g) {
        int margin = 10;
        Dimension dim = getSize();
        super.paintComponent(g);
        g.setColor(Color.black);
        GameState.update();

        g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);

        for(Bullet j : GameState.getEnBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Enemy j : GameState.getEnemies()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Bullet j : GameState.getPlayBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}

        g.drawImage(p.getImage(),p.getX(),p.getY(),null);
    }




public void refreshImage()
{
    this.removeAll();
    repaint();
}


public void actionPerformed(ActionEvent e) {


}


}

另一件事是在其他一些类中,您在 actionPerformed 方法上使用了 @Override 。我的 IDE 不喜欢这样,尽管它确实可以编译。它说“实现接口方法时不允许@Override”。

希望这对你有用。

Ok, so I think I have figured most of it out.

You have a couple problems.

First, you should only see a grey screen with a black rectangle in the middle since you have nothing in your Bullet and Enemy Arrays. This is what I got when I ran your code (after removing references to endEvent cuz it couldn't find it). So to fix this, just give it something to draw

The second problem is apparent once you give it something to draw. I manually put in a line of code to draw the Player, for which I used one of my own pngs. When you do this it will fail to compile with a null pointer exception. The reason is because in your GameView class, you have your Graphics object called "graphics" set to null, but then you proceed to call paintComponents(graphics). As mentioned before, this only compiled before because you never actually drew anything. To fix this, you can just remove

public void paintComponents (Graphics g)
{

    for(Bullet j : GameState.getEnBullets()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    for(Enemy j : GameState.getEnemies()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    for(Bullet j : GameState.getPlayBullets()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    this.paint(g);

}

and let the overridden paintComponent(Graphics g) method above it do all the work. Additionally, instead of the paintComponents(graphics) calls, use repaint(). Also you can get rid of the first call to paintComponents(graphics) in the constructor as it will paint the first time by default. If you really want to use your own method then you have to create a Graphics object and pass that in.

Lastly, in the overridden paintComponents(Graphics g) method, you have the last line being to draw the giant black box. This will then cover up anything you've drawn before. So you should have that as the first line and draw everything else in order such that the thing you want to be on top should be drawn last. I was able to get my test image to show up with the following code for that class. I don't think I changed anything else.

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class GameView extends JComponent implements ActionListener{

/**
 * 
 */
private static final long serialVersionUID = -2869672245901003704L;
private boolean liveGame;//used so that buttons cannot be clicked after game is complete
private GameState gs;
private Player p;
private int w, h;

public GameView(int width, int height)
{
    liveGame = true;
    gs = new GameState();
    GameState.init(width, height);
    p = new Player(width/2,(height*7)/8);
    this.setBackground(Color.BLACK);
    w = width;
    h = height;
}
   @Override
    public Dimension getMinimumSize() {
        return new Dimension(w, h);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(w, h);
    }

    @Override
    public void paintComponent(Graphics g) {
        int margin = 10;
        Dimension dim = getSize();
        super.paintComponent(g);
        g.setColor(Color.black);
        GameState.update();

        g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);

        for(Bullet j : GameState.getEnBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Enemy j : GameState.getEnemies()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
        for(Bullet j : GameState.getPlayBullets()){
            g.drawImage(j.getImage(),j.getX(), j.getY(), null);}

        g.drawImage(p.getImage(),p.getX(),p.getY(),null);
    }




public void refreshImage()
{
    this.removeAll();
    repaint();
}


public void actionPerformed(ActionEvent e) {


}


}

The other thing is in some of your other classes you have @Override over the actionPerformed method. My IDE doesn't like that, although it does compile. It says "@Override is not allowed when implementing interface methods."

Hopefully this works for you.

窝囊感情。 2024-11-21 01:42:59

尝试添加 repaint();对内容窗格进行更改后。我认为并发不会成为问题,除非你阻塞了你的 EDT。

try adding repaint(); after you make a change to a content pane. I dont think concurrency is going to be a problem unless you clog up your EDT.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文