简体   繁体   English

从零开始的2D自上而下Java(1.8)游戏(无)

[英]2D Top-Down Java (1.8) Game from Scratch(nothing)

So, first of all this is my first time posting and I am trying to make a top-down game with java(1.8) and IntelliJ, nothing else. 因此,首先,这是我的第一次发布,我正在尝试使用java(1.8)和IntelliJ制作自上而下的游戏,除此之外没有别的。 I have all of my code good and done(for making the sprite show up), I test it and it keeps giving me error messages saying that certain parts are invalid. 我已经完成了所有代码(为了使精灵显示出来),我对其进行了测试,并且不断向我显示错误消息,指出某些部分无效。 It is supposed to display an image (character) on the screen in the top right here is all code and please keep in mind that I do not have this fully finished: 应该在屏幕的右上角显示图像(字符),这里是所有代码,请记住,我还没有完全完成此操作:

Game.java Game.java

package main;

import main$entities.Player;
import main$gfx.ImageLoader;
import main$gfx.SpriteSheet;

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.lang.*;

public class Game extends Canvas implements Runnable {
    private static final long serialVersionUID = 1L;
    public static final int WIDTH = 700, HEIGHT = 400, SCALE = 1;
    public static boolean running = false;
    public Thread gameThread;

    private BufferedImage spriteSheet;

    private Player player;

    public void init(){
        ImageLoader loader = new ImageLoader();
        spriteSheet = loader.load("./spritesheet.png");

        SpriteSheet ss = new SpriteSheet(spriteSheet);

        player = new Player(0, 0, ss);
    }

    public synchronized void start(){
        if(running)return;
        running = true;
        gameThread = new Thread(this);
        gameThread.start();
    }
    public synchronized void stop(){
        if(!running)return;
        running = false;
        try {
            gameThread.join();
        } catch (InterruptedException e) {e.printStackTrace();}
    }

    public void run(){
        long lastTime = System.nanoTime();
        final double amountOfTicks = 60D;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;

        while(running){
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            if(delta >= 1){
                tick();
                delta--;
            }
            render();
        }
        stop();
    }
    public void tick(){
        player.tick();
    }
    public void render(){
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null){
            createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();
        // Render Here

        g.fillRect(0, 0, WIDTH * SCALE, HEIGHT * SCALE);

        player.render(g);

        // End Render
        g.dispose();
        bs.show();
    }

    public static void main(String[] args){
        Game game = new Game();
        game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

        JFrame frame = new JFrame("Tile RPG");
        frame.setSize(WIDTH *SCALE, HEIGHT * SCALE);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(game);
        frame.setVisible(true);

        game.start();
        }
    }

ImageLoader.java ImageLoader.java

package main$gfx;

import javax.imageio.ImageIO;

import java.awt.image.BufferedImage;
import java.io.IOException;

public class ImageLoader {

    public BufferedImage load(String path){
        try {
            return ImageIO.read(getClass().getResource(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

SpriteSheet.java SpriteSheet.java

package main$gfx;

import java.awt.image.BufferedImage;

public class SpriteSheet {

    private BufferedImage sheet;

    public SpriteSheet(BufferedImage sheet){
        this.sheet = sheet;
    }

    public BufferedImage crop(int col, int row, int w, int h){
        return sheet.getSubimage(col * 16, row * 16, w, h);
    }

}

Player.java 播放器

package main$entities;

import main.Game;
import main$gfx.SpriteSheet;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Player implements KeyListener{

    private int x, y;
    private SpriteSheet ss;
    private boolean up = false, dn = false, lt = false, rt = false;
    private final int SPEED = 3;

    public Player(int x, int y, SpriteSheet ss){
        this.x = x;
        this.y = y;
        this.ss = ss;
    }

    public void tick(){
        if(up){
            y -= SPEED;
        }
        if(dn){
            y += SPEED;
        }
        if(lt){
            x -= SPEED;
        }
        if(rt){
            x += SPEED;
        }
    }

    public void render(Graphics g){
        g.drawImage(ss.crop(0 ,0, 16, 16), x, y, 16 * Game.SCALE, 16 * Game.SCALE, null);
    }

    public void keyTyped(KeyEvent e) {}

    public void keyPressed(KeyEvent e) {

    }

    public void keyReleased(KeyEvent e) {

    }
}

The error messages(It gives me multiple messages, each time is different // = what is on that line, so you don't have to find it by counting, your welcome): 错误消息(它给我多条消息,每次都不同// =该行上的内容,因此您不必通过计数来表示欢迎):

First time I run the Game.java: 第一次运行Game.java:

Exception in thread "Thread-2" java.lang.NullPointerException
    at main.Game.tick(Game.java:64)    // player.tick();
    at main.Game.run(Game.java:56)    // tick();
    at java.lang.Thread.run(Thread.java:745)    // this is in the JDK itself

Process finished with exit code 0

Second(and all that proceed) time I run the Game.java: 第二次(以及所有后续过程)我运行Game.java:

Exception in thread "Thread-2" java.lang.NullPointerException
    at main.Game.render(Game.java:77)    // player.render(g);
    at main.Game.run(Game.java:59)    // render();
    at java.lang.Thread.run(Thread.java:745)    // this is in the JDK itself

Process finished with exit code 0

That game.start(); 那个game.start(); takes all the responsibility. 承担所有责任。 Your Game class is not extending a Thread , the thread itself will start automatically right after you instantiate your game's class, since the thread is created inside the game class. 您的Game类未扩展Thread ,线程实例将在实例化game's类后立即自动启动,因为该线程是在游戏类内部创建的。 So remove : 因此删除:

game.start();

Btw you fall on trap : 顺便说一句,你陷入陷阱:

public static final int WIDTH = 700, HEIGHT = 400;

won't work, because those fields hide another fields, why ? 将不起作用,因为这些字段隐藏了另一个字段, 为什么 because 因为

WIDTH & HEIGHT is preserved arguments for WIDTHHEIGHT是保留的参数

.fillRect(...);

It's because you never call the init() method and, therefore the player and the spriteheet never gets created 这是因为您永远不会调用init()方法,因此永远不会创建播放器和Spriteheet

You can add a constructor to the Game class like this: 您可以像下面这样向Game类添加一个构造函数:

public Game() {
    init();
}

Or you can add the following line in the main method: 或者,您可以在main方法中添加以下行:

public static void main(String[] args){
    Game game = new Game();
    game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

    JFrame frame = new JFrame("Tile RPG");
    frame.setSize(WIDTH *SCALE, HEIGHT * SCALE);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.add(game);
    frame.setVisible(true);

    // Add this line
    game.init();        

    game.start();
    }
} 

But I prefer the first way 但我更喜欢第一种方式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM