请原谅我英语不好。我在实现2d相机时遇到了问题。我让相机跟随玩家,直到它接近游戏级别的边缘,在那里只有玩家移动,摄像机停止。我做这个很容易,但我的问题是相机不合适。相机继续移动一个额外的像素,每次你到达边缘的游戏水平的极限,在所有四个方向(代码我张贴只显示水平移动。我这样做是为了简单)。这意味着,如果您移动40次在游戏的左边边缘附近来回移动,相机将移动额外的40像素右!我不知道怎么解决这个问题。我发布了一个非常简单的版本,从我的原始代码下面,并使它尽可能小,以显示程序如何工作。下面只需将播放器和摄像机水平地移动到屏幕上。
这是'theGamePanel‘类(它是主类) :-
public class TheGamePanel extends JPanel implements Runnable, KeyListener
{
private boolean left, right;
private float cameraX, cameraY;
private World world = new World();
private Player player = new Player();
public TheGamePanel()
{
//setting the size of panel
}
public static void main(String[] args)
{
//setting the window
}
public void paint(Graphics g)
{
super.paint(g);
// drawing the game-level and player
g.translate((int)cameraX, (int)cameraY);
world.paint(g);
player.paint(g);
g.translate(-(int)cameraX, -(int)cameraY);
}
public void upd()
{
player.update(left, right, this);
}
@Override
public void run()
{
// game-loop
}
@Override
public void keyPressed(KeyEvent e)
{
int code = e.getKeyCode();
if(code == KeyEvent.VK_LEFT)
{
left = true;
}
if(code == KeyEvent.VK_RIGHT)
{
right = true;
}
}
@Override
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_LEFT)
{
left = false;
}
if(e.getKeyCode() == KeyEvent.VK_RIGHT)
{
right = false;
}
}
@Override
public void keyTyped(KeyEvent e)
{
}
//to set camera position
public void setCameraX(float cameraDx)
{
cameraX += cameraDx;
}
}这是“玩家”班。这门课是玩家和摄像机运动发生的地方。然后相机的x和值返回到“TheGamePanel”:-
public class Player
{
private float x, y;
private float dx = 1;
private int width = 32, height = 32;
private float leftLimit, rightLimit;
public Player()
{
//player's initial x and y coordinates
x = 320;
y = 240;
//camera's limit (where the camera needs to stop following player)
leftLimit = x;
rightLimit = 960;
}
public void paint(Graphics g)
{
//for painting the player
g.setColor(Color.GREEN);
g.fillRect((int)x, (int)y, width, height);
}
//to move player and camera
public void update(boolean left, boolean right, TheGamePanel panel)
{
if(left == true)
{
x -= dx;
if(x > leftLimit && x < rightLimit)
{
panel.setCameraX(dx);
}
}
if(right == true)
{
x += dx;
if(x > leftLimit && x < rightLimit)
{
panel.setCameraX(-dx);
}
}
}
}最后是“世界”班。这个类用于简单地在背景中绘制一个大的地图(级别) :-
public class World
{
private BufferedImage map;
private int tileWd = 32, tileHi = 32;
public World()
{
try
{
map = ImageIO.read(new File("map1.png"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void paint(Graphics g)
{
//simply paints a game-level in the background
}
}如果有什么不能理解的,请告诉我。我会增加更多细节。
发布于 2014-12-15 23:59:56
考虑一下玩家站在地图右边边缘的情况。只要点击一下“右”键,他就会离开摄像机--跟踪区域,这样相机就不会移动。一个快速点击“左”键将他移回摄像机-跟踪区域。相机将向左移动"dx“单位。如果我是对的,这将使玩家慢慢地靠近比赛的右边边缘。
(为了找到这样的bug,我通常会在代码中乱扔System.out.println消息。如果有很多消息,我会把它们写到一个文件中,然后对关键字进行文本搜索)
发布于 2014-12-16 00:14:44
你有你的相机的位置(cameraX,cameraY),但是播放器没有位置?
只需为播放器创建一个位置(playerX,playerY)
改变油漆如下:
public void paint(Graphics g)
{
super.paint(g);
// drawing the game-level and player
g.translate((int)cameraX, (int)cameraY);
world.paint(g);
g.translate((int)playerX, (int)playerY);
player.paint(g);
g.translate(-(int)(playerX+cameraX), -(int)(playerY+cameraY));
}当玩家靠近边界时,不要移动摄像机,而只能移动玩家。
发布于 2014-12-16 03:06:55
我相信以下的改变解决了问题:
球员班:
//to move player and camera
public void update(boolean left, boolean right, TheGamePanel panel)
{
if(left == true)
{
x -= dx;
if(x > leftLimit && x < rightLimit)
{
panel.setCameraX(dx);
}
}
if(right == true)
{
if(x > leftLimit && x < rightLimit)
{
panel.setCameraX(-dx);
}
x += dx; // Only change: moved this line AFTER the if block
}
}通过测试x,在向左移动时更改x,在向右移动时更改x之前,您可以补偿每次到达其中一个边界时积累的错误。
无论如何,我建议您改变解决问题的方法,以便使代码更易于维护和更灵活。一种方法是根据当前玩家在每一帧上的位置来计算摄像机的位置。
注意:如果方法translate(int, int)不是增量的,则TheGamePanel类的paint()方法中的行g.translate(-(int)cameraX, -(int)cameraY);是不必要的。
问候
https://stackoverflow.com/questions/27495153
复制相似问题