首页 > 解决方案 > Java swing 游戏 JPanel 布局辅助

问题描述

我正在制作一个游戏,它有 3 个部分到 JFrame、游戏地图、“玩家视图”:只是一个玩家移动的动画,希望以后包括不同的敌人设计,最后是我拥有的库存部分还没开始呢

就类和方法布局而言,让我的 JPanel 的所有这 3 个部分能够相互通信并根据当前情况动态变化的最佳方式是什么(当他们的瓷砖与另一个瓷砖碰撞时让玩家视图显示敌人或者如果玩家不移动,它不会更新)。

我不介意重写整个游戏,这是我的第一款游戏,希望在结构上得到一些帮助。

而且我不确定 paintComponent 的工作原理或 repaint() 方法。或者如何调用 draw(Graphics g) 来制作图形???

上下文和测试代码:

文本游戏面板.java:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Random;

public class TextGamePanel extends JPanel implements ActionListener{

    private static final int HEIGHT = 30, WIDTH = 30, MAPVISIBILITY = 8;
    private static final int SCREEN_WIDTH = 1080;
    private static final int SCREEN_HEIGHT = 1080;
    private static final int UNIT_SIZE = 36;
    private static final int DELAY = 10;
    private String[][] mapBlank = new String[HEIGHT][WIDTH];
    private ArrayList<Enemies> enemyList = new ArrayList<Enemies>();
    private Random random = new Random();
    private Players player;
    private int turnCounter = 0;
    Timer timer;
    boolean active = false , movementMade = false;

    TextGamePanel(){
        this.setPreferredSize(new Dimension(1920, 1080));
        this.setFocusable(true);
        this.addKeyListener(new MyKeyAdapter());
        startGame();
    }
    public void startGame(){
        newPlayer();
        active = true;
        timer = new Timer(DELAY, this);
        timer.start();
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        draw(g);
    }
    public void makeMap(){
        for(int row = 0; row < mapBlank.length; row++){
            for(int col = 0; col < mapBlank[row].length; col++){
               mapBlank[row][col] = "";
            }
        }
        for(Enemies enemy : enemyList){
            mapBlank[enemy.getXPos()][enemy.getYPos()] = " *";
        }
        mapBlank[player.getXPos()][player.getYPos()] = " ^";
    }
    public void draw(Graphics g){

        makeMap();
        // These loops generate the 
        g.setColor(new Color(69, 69, 69));
        g.fillRect(1080, 0, 840, 360);
        g.setFont(new Font("Times Roman", Font.BOLD, 36));
        g.setColor(new Color(74, 74, 74));
        for(int x = 0; x < 20; x++){
            g.drawString(randomString(50), 1020, UNIT_SIZE + x*UNIT_SIZE/2);
        }
        for(int i = 0; i < 2; i++){
            for(int x = 0; x < 13; x++){
                g.setColor(new Color(0+x*10, 0+x*10, 0+x*10));
                g.setFont(new Font("Times Roman", Font.BOLD, 10+x*2));
                g.drawString(randomString(200), 1020, 268 + x * 8);
            }
        }

        //makes the map background grey
        g.setColor(new Color(69, 69, 69));
        g.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

        //Makes light for context of player view range
        g.setColor(new Color(227, 201, 109, 50));
        g.fillOval((int)(((player.getXPos()) * UNIT_SIZE) - MAPVISIBILITY/2 * UNIT_SIZE), (int)(((player.getYPos()) * UNIT_SIZE) - MAPVISIBILITY/2 *UNIT_SIZE), (int)((MAPVISIBILITY +1) * UNIT_SIZE), (int)((MAPVISIBILITY +1) * UNIT_SIZE));
        g.setColor(new Color(227, 180, 109, 50));
        g.fillOval((int)(((player.getXPos()) * UNIT_SIZE) - (MAPVISIBILITY/2 - 1) * UNIT_SIZE), (int)(((player.getYPos()) * UNIT_SIZE) - (MAPVISIBILITY/2 - 1) *UNIT_SIZE), (int)((MAPVISIBILITY -1) * UNIT_SIZE), (int)((MAPVISIBILITY -1) * UNIT_SIZE));
        g.setColor(new Color(240, 110, 67, 50));
        g.fillOval((int)(((player.getXPos()) * UNIT_SIZE) - (MAPVISIBILITY/2 - 2.5) * UNIT_SIZE), (int)(((player.getYPos()) * UNIT_SIZE) - (MAPVISIBILITY/2 - 2.5) *UNIT_SIZE), (int)((MAPVISIBILITY -4) * UNIT_SIZE), (int)((MAPVISIBILITY -4) * UNIT_SIZE));
        g.setColor(new Color(255, 255, 255));
        g.setFont(new Font("Times Roman", Font.BOLD, 36));

        //draws the grid
        for(int i = 0; i < SCREEN_HEIGHT/UNIT_SIZE; i++){
            g.drawLine(i*UNIT_SIZE, 0, i*UNIT_SIZE, SCREEN_HEIGHT);
        }
        for(int i = 0; i < SCREEN_WIDTH/UNIT_SIZE; i++){
            g.drawLine(0, i*UNIT_SIZE, SCREEN_WIDTH, i*UNIT_SIZE);
        }
        
        //draws only yourself and enemy around you given MAPVISIBILITY/2 = view range
        int xIndex = -1, yIndex = -1;
        for(int row = player.getXPos() - MAPVISIBILITY/2; row < player.getXPos() + 1 + MAPVISIBILITY/2; row++){
            xIndex ++;
            for(int col = player.getYPos() - MAPVISIBILITY/2; col < player.getYPos() + 1 + MAPVISIBILITY/2; col++){
                yIndex++;
                try{
                    g.drawString(mapBlank[row][col], row * UNIT_SIZE, (col + 1) * UNIT_SIZE);
                }catch(Exception e){
                }
            }
        }

        // inventory section (yet to be made)
        g.setColor(Color.blue);
        g.fillRect(1080, 360, 840, 720);
    }

    public void movementPhase(){
        turnCounter ++;
        updateEnemyMovement();
        if(turnCounter == 2){
            turnCounter = 0;
            newEnemy();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e){
        if(active){ 
        }
    }

    public class MyKeyAdapter extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e){
            switch(e.getKeyCode()){
                case KeyEvent.VK_Q: // Move diagonal left up.
                    if(player.getXPos() > 0 && player.getYPos() > 0){
                        player.setXPos(player.getXPos() - 1);
                        player.setYPos(player.getYPos() - 1);
                        movementMade = true;
                    }
                    break;
                case KeyEvent.VK_E: // Move diagonal right up.
                    if(player.getXPos() < HEIGHT - 1 && player.getYPos() > 0){
                        player.setXPos(player.getXPos() + 1);
                        player.setYPos(player.getYPos() - 1);
                        movementMade = true;
                    }
                    break;
                case KeyEvent.VK_Z: // Move diagonal left down.
                    if(player.getXPos() > 0 && player.getYPos() < WIDTH - 1){
                        player.setXPos(player.getXPos() - 1);
                        player.setYPos(player.getYPos() + 1);
                        movementMade = true;
                    }
                    break;
                case KeyEvent.VK_C: // Move diagonal right down.
                    if(player.getYPos() < WIDTH - 1 && player.getXPos() < HEIGHT - 1){
                        player.setXPos(player.getXPos() + 1);
                        player.setYPos(player.getYPos() + 1);
                        movementMade = true;
                    }
                    break;
                case KeyEvent.VK_W: // Move up.
                    if(player.getYPos() > 0){
                        player.setYPos(player.getYPos() - 1);
                        movementMade = true; 
                    } 
                    break;
                case KeyEvent.VK_X: // Move down.
                    if(player.getYPos() < WIDTH - 1){
                        player.setYPos(player.getYPos() + 1);
                        movementMade = true;
                    }
                    
                    break;
                case KeyEvent.VK_A: // Move left.
                    if(player.getXPos() > 0){
                        player.setXPos(player.getXPos() - 1);
                        movementMade = true;
                    }
                    
                    break;
                case KeyEvent.VK_D: // Move right.
                    if(player.getXPos() < HEIGHT - 1){
                        player.setXPos(player.getXPos() + 1);
                        movementMade = true;
                    }
                    break;
                case KeyEvent.VK_S: // Dont Move.
                    movementMade = true;
                    break;
            }
            if(movementMade){
                movementPhase();
                movementMade = false;
            }
            repaint();
        }
    }
    public void updateEnemyMovement(){

        Iterator i = (Iterator) enemyList.iterator();
        Enemies enemy = new Enemies();

        while(i.hasNext()){
           enemy = (Enemies) i.next();
           enemy.move(player.getXPos(), player.getYPos());
           if(enemy.getXPos() == player.getXPos() && enemy.getYPos() == player.getYPos()){
               i.remove();
           }
        }
     }

    public void newPlayer(){
        player = new Players(random.nextInt((int)SCREEN_WIDTH/UNIT_SIZE), random.nextInt((int)SCREEN_HEIGHT/UNIT_SIZE));
    }
    public void newEnemy(){
        enemyList.add(new Enemies(random.nextInt(HEIGHT), random.nextInt(WIDTH)));
    }
    public String randomString(int n) {
 
        int leftLimit = 49; //'0'
        int rightLimit = 122; //'z'
        int targetStringLength = n;
        Random random = new Random();
        StringBuilder buffer = new StringBuilder(targetStringLength);
        for (int i = 0; i < targetStringLength; i++) {
            int randomLimitedInt = leftLimit + (int) 
              (random.nextFloat() * (rightLimit - leftLimit + 1));
            buffer.append((char) randomLimitedInt);
        }
        String generatedString = buffer.toString();
    
        return(generatedString);
    }
}

`

Players.java :

公共类玩家{

private int x, y;

public Players(){

}
public Players(int x, int y){
  this.x = x;
  this.y = y;
}
/** Positional Methods */
public int getXPos(){
    return x;
 }
 public int getYPos(){
    return y;
 }
 public void setXPos(int x){
    this.x = x;
 }
 public void setYPos(int y){
    this.y = y;
 }  

}

`

Enemies.java:

public class Enemies {

    private int x, y;

    public Enemies(){

    }
    public Enemies(int x, int y){
        this.x = x;
        this.y = y;
    }
    /** Positional Methods */
    public int getXPos(){
        return x;
     }
     public int getYPos(){
        return y;
     }
     public void setXPos(int x){
        this.x = x;
     }
     public void setYPos(int y){
        this.y = y;
     }
     /** Enemy Movement Method */
     public void move(int playerX, int playerY){
        if(getXPos() == playerX && getYPos() == playerY){ // x = playerX & y = playery
           }/** Diagonal right down */
           else if(getXPos() < playerX && getYPos() < playerY){ // x < playerX & y < playerY
              setXPos(getXPos() + 1);  // x + 1
              setYPos(getYPos() + 1);  // y + 1
           }/** Diagonal right up */
           else if(getXPos() > playerX && getYPos() < playerY){ // x > playerX & y < playerY
              setXPos(getXPos() - 1);  // x - 1
              setYPos(getYPos() + 1);  // y + 1
           }/** Diagonal left down */
           else if(getXPos() < playerX && getYPos() > playerY){ // x < playerX & y > playerY
              setXPos(getXPos() + 1);  // x + 1
              setYPos(getYPos() - 1);  // y - 1
           }/** Diagonal right up */
           else if(getXPos() > playerX && getYPos() > playerY){ // x > playerX & y > playerY
              setXPos(getXPos() - 1);  // x - 1
              setYPos(getYPos() - 1);  // y - 1
           }/** Down */
           else if(getXPos() < playerX && getYPos() == playerY){ // x < playerX & y = playerY
              setXPos(getXPos() + 1);  // x + 1
           }/** Up */
           else if(getXPos() > playerX && getYPos() == playerY){ // x > playerX & y = playerY
              setXPos(getXPos() - 1);  // x - 1
           }/** Right */
           else if(getXPos() == playerX && getYPos() < playerY){ // x = playerX & y < playerY
              setYPos(getYPos() + 1);  // y + 1
           }/** Left */
           else if(getXPos() == playerX && getYPos() > playerY){ // x = playerX & y > playerY
              setYPos(getYPos() - 1);  // y - 1
           }
      }
}

`

TextGameFrame.java : 

导入 javax.swing.*;

公共类 TextGameFrame 扩展 JFrame{

TextGameFrame(){

    this.add(new TextGamePanel());
    this.setTitle("Text Game");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);
    this.pack();
    this.setVisible(true);
    this.setLocationRelativeTo(null);

}

}

`

TextGameMain.java :


public class TextGameMain{
    public static void main(String[] args){

        new TextGameFrame();

    }
}

`

标签: javaswinguser-interface

解决方案


推荐阅读