gpt4 book ai didi

Java Applet 游戏 2D 窗口滚动

转载 作者:行者123 更新时间:2023-12-03 03:46:51 25 4
gpt4 key购买 nike

我正在尝试在 Java Applet 中开发 2D RPG 游戏。现在我有一个简单的椭圆形,玩家可以使用向左、向右、向上和向下移动,并且与小程序边界的碰撞会阻止它们。问题是,我想创建一个玩家可以移动的巨大世界(2000px x 2000x)。但是,我希望他们一次只能看到 600 像素 x 400 倍的屏幕。如果他们继续向右移动,我希望屏幕跟随他们,向上、向下和向左也是如此。谁能告诉我该怎么做?这是到目前为止我的代码:

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

}
}

最佳答案

这是滚动可视区域的基本示例,其中虚拟世界比 View 区域大。

这基本上维护了一些参数。它维护世界中 View 的顶部/左侧所在的点以及玩家在世界中的位置。

这些值将转换回现实世界坐标(其中 0x0 是可视区域的左上角)。

这些示例还使用 BufferedImage#getSubImage 来简化渲染。您也可以计算 map 到 View 的偏移位置,但这取决于需要......

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MiddleEarth {

public static void main(String[] args) {
new MiddleEarth();
}

public MiddleEarth() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new WorldPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class WorldPane extends JPanel {

private BufferedImage map;
private BufferedImage party;
private Point viewPort;
private Point partyPoint;
private BufferedImage view;

public WorldPane() {
try {
map = ImageIO.read(getClass().getResource("/MiddleEarth.jpg"));
party = ImageIO.read(getClass().getResource("/8BitFrodo.png"));

viewPort = new Point(0, (map.getHeight() / 2) - 100);
partyPoint = new Point(party.getWidth() / 2, (map.getHeight() / 2)); // Virtual Point...

} catch (IOException exp) {
exp.printStackTrace();
}

InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "goRight");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "goLeft");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "goUp");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "goDown");

am.put("goRight", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
moveParty(10, 0);
}
});
am.put("goLeft", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
moveParty(-10, 0);
}
});

am.put("goUp", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
moveParty(0, -10);
}
});
am.put("goDown", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
moveParty(0, 10);
}
});

}

protected void moveParty(int xDelta, int yDelta) {
partyPoint.x += xDelta;
partyPoint.y += yDelta;
Point view = fromWorld(partyPoint);
if (view.x > getWidth() - (party.getWidth() / 2)) {
viewPort.x += xDelta;
if (viewPort.x + getWidth() > map.getWidth()) {
viewPort.x = map.getWidth() - getWidth();
partyPoint.x = map.getWidth() - (party.getWidth() / 2) - 1;
}
invalidate();
} else if (view.x < party.getWidth() / 2) {
viewPort.x += xDelta;
if (viewPort.x < 0) {
viewPort.x = 0;
partyPoint.x = (party.getWidth() / 2);
}
invalidate();
}
System.out.println(view + "; " + getHeight());
if (view.y > getHeight() - (party.getHeight() / 2)) {
viewPort.y += yDelta;
if (viewPort.y + getHeight() > map.getHeight()) {
viewPort.y = map.getHeight() - getHeight();
partyPoint.y = map.getHeight() - (party.getHeight() / 2) - 1;
}
invalidate();
} else if (view.y < party.getHeight() / 2) {
viewPort.y += yDelta;
if (viewPort.y < 0) {
viewPort.y = 0;
partyPoint.y = (party.getHeight() / 2);
}
invalidate();
}
repaint();
}

@Override
public void invalidate() {
view = null;
super.invalidate();
}

public BufferedImage getView() {

if (view == null && getWidth() > 0 && getHeight() > 0) {

view = map.getSubimage(viewPort.x, viewPort.y, getWidth(), getHeight());

}

return view;

}

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

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (map != null) {
g2d.drawImage(getView(), 0, 0, this);

Point real = fromWorld(partyPoint);

int x = real.x - (party.getWidth() / 2);
int y = real.y - (party.getHeight()/ 2);
g2d.drawImage(party, x, y, this);
}
g2d.dispose();
}

protected Point fromWorld(Point wp) {

Point p = new Point();

p.x = wp.x - viewPort.x;
p.y = wp.y - viewPort.y;

return p;

}
}
}

关于Java Applet 游戏 2D 窗口滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16050723/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com