2

Java アプレットで 2D RPG ゲームを開発しようとしています。現在、プレイヤーが左、右、上、下を使用して移動できる単純な楕円があり、アプレットの境界に対する衝突がそれらを停止します。問題は、プレイヤーが移動できる巨大な世界 (2000px x 2000x) を作成したいということです。ただし、一度に 600px x 400x の画面だけを表示したいのです。右に移動し続ける場合は、画面がそれに追従するようにします。上下左右も同様です。誰でもこれを行う方法を教えてもらえますか? これまでの私のコードは次のとおりです。

import java.awt.*;
import java.awt.event.KeyEvent;
import java.applet.Applet;
import java.awt.event.KeyListener;
import javax.swing.*;

public class Main extends Applet implements Runnable, KeyListener
{
    private Image dbImage;
    private Graphics dbg;
    Thread t1;
    int x = 0;
    int y = 0;
    int prevX = x;
    int prevY = y;
    int radius = 40;
    boolean keyReleased = false;

    public void init()
    {
        setSize(600, 400);

    }

    public void start()
    {

        addKeyListener(this);
        t1 = new Thread(this);
        t1.start();
    }

    public void destroy()
    {
    }

    public void stop()
    {
    }

    public void paint(Graphics g)
    {
        //player
        g.setColor(Color.RED);
        g.fillOval(x, y, radius, radius);
    }

    public void update(Graphics g)
    {

        dbImage = createImage (this.getSize().width, this.getSize().height);
        dbg = dbImage.getGraphics();
        // initialize buffer
        if (dbImage == null)
        {
        }

        // clear screen in background
        dbg.setColor(getBackground());
        dbg.fillRect(0, 0, this.getSize().width, this.getSize().height);

        // draw elements in background
        dbg.setColor(getForeground());
        paint(dbg);
        // draw image on the screen
        g.drawImage(dbImage, 0, 0, this);
    }

    @Override
    public void run()
    {
        while (true)
        {
            //x++;
            repaint();

            try
            {
                t1.sleep(17);
            }
            catch (Exception e)
            {
            }
        }
    }

    public boolean CheckCollision(String dir)
    {
        if (x <= 0 && dir.equals("L"))
        {
            x = prevX;
            return true;
        }
        else if (y <= 0 && dir.equals("U"))
        {
            y = prevY;
            return true;
        }
        else if (x >= (getWidth() - radius) && dir.equals("R"))
        {
            System.out.println(getWidth());
            x = prevX;
            return true;
        }
        else if (y >= (getHeight() - radius) && dir.equals("D"))
        {
            y = prevY;
            return true;
        }
        return false;
    }

    @Override
    public void keyPressed(KeyEvent e)
    {
        switch (e.getKeyCode())
        {
        case KeyEvent.VK_RIGHT:
            if (!CheckCollision("R"))
            {
            x += 4;
            prevX = x;
            }
            break;
        case KeyEvent.VK_LEFT:
            if (!CheckCollision("L"))
            {
            x -= 4;
            prevX = x;
            }
            break;
        case KeyEvent.VK_UP:
            if (!CheckCollision("U"))
            {
            y -= 4;
            prevY = y;
            }
            break;
        case KeyEvent.VK_DOWN:
            if (!CheckCollision("D"))
            {
            y += 4;
            prevY = y;
            }
            break;
        }

    }

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

    }

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

    }
}
4

2 に答える 2

1

これが私のエンジンでのやり方です。

2 つの変数OffSetXを保持し、OffSetY

そして、このようにプレーヤーを中心に置くために、すべてのステップでそれらを計算します。

OffSetX = 0;
OffSetY = 0;
if (MAP_WIDTH > WINDOW_WIDTH) {
    OffSetX = Math.round(WINDOW_WIDTH / 2 - obj.getX() - TILE_SIZE);
    OffSetX = Math.min(OffSetX, 0);
    OffSetX = Math.max(OffSetX, WINDOW_WIDTH - MAP_WIDTH);
}
if (MAP_HEIGHT > WINDOW_HEIGHT) {
    OffSetY = Math.round(WINDOW_HEIGHT / 2 - obj.getY() - TILE_SIZE);
    OffSetY = Math.min(OffSetY, 0);
    OffSetY = Math.max(OffSetY, WINDOW_HEIGHT - MAP_HEIGHT);
}

次に、その位置にマップを描画します(OffSetX, OffSetY)。つまり、描画するオブジェクトの元の位置にこれらを追加するだけです。

表示されていないオブジェクトのレンダリングをスキップしたい場合があります。

于 2013-04-17T03:16:37.703 に答える