我正在尝试为我正在制作的 2D 游戏实现一个摄像头......目标是让摄像头将玩家保持在中心,并使精灵相对于摄像头。
为了掌握normalocity 的帖子,我尝试通过制作一个 Camera Test 项目开始简单,在该项目中,我通过将精灵绘制到 JPanel 并移动“相机”对象(即 JPanel)来模拟相机,然后设置精灵的 x,y 相对于此。
正如我所说,相机是 JPanel ......我添加了一个“世界”,它是一个带有x,y of 0,0
, 和的类w=1000, h=1000
。我已经包含了精灵相对于世界的位置以及相机。当我向上移动相机时,精灵向下移动,玩家按预期停留在中间..
但如果我继续按下,精灵似乎会不断地绘制自己。
我的问题是:
- 给出下面的代码,我在实现相机方面是否走在正确的轨道上?
- 为什么精灵开始在那里绘制自己?它应该从 viewPort/JPanel 上消失
谢谢!
现在PaintComponent(g)
添加后,我的 JPanel bg 灰色现在会滑落。这应该发生吗?
编辑:我的程序的 SSCCE:
主类:
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class MainSSCCE extends JFrame {
static MainSSCCE runMe;
public MainSSCCE() {
JFrame f = new JFrame("Camera Test");
CameraSSCCE cam = new CameraSSCCE(0, 0, 500, 500);
f.add(cam);
f.setSize(cam.getWidth(), cam.getHeight());
f.setVisible(true);
f.setResizable(false);
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation( (screensize.width - f.getWidth())/2,
(screensize.height - f.getHeight())/2-100 );
}
public static void main(String[] args) {
runMe = new MainSSCCE();
}
}
相机类:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
//Camera is the JPanel that will draw all objects... each object location will be in relation to the World
public class CameraSSCCE extends JPanel implements KeyListener {
//add world to camera...
private static final long serialVersionUID = 1L;
private int camX, camY, camH, camW;
private SpriteSSCCE sprite;
private PlayerSSCCE player;
private WorldSSCCE world;
public CameraSSCCE(int x, int y, int w, int h) {
camX = x;
camY = y;
camW = w;
camH = h;
sprite = new SpriteSSCCE(this, 300, 300, 20, 20);
player = new PlayerSSCCE(this, camW/2, camH/2, 25, 40);
world = new WorldSSCCE(this, 0, 0, 1000, 1000);
addKeyListener(this);
setFocusable(true);
}
public int getWidth() {
return camW;
}
public int getHeight() {
return camH;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//cam is 500 x 500
g.setColor(Color.gray);
g.fillRect(camX, camY, camW, camH);
//draw sprite at JPanel location if in camera sight
if (((sprite.getX()-camX) >= camX) && ((sprite.getX()-camX) <= (camX+camW)) && ((sprite.getY()-camY) >= camY) && ((sprite.getY()-camY) <= (camY+camH))) {
g.setColor(Color.green);
g.fillRect(sprite.getX()-camX, sprite.getY()-camY, 20, 20);
//Cam Sprite Location
g.setColor(Color.white);
g.drawString("Camera Sprite Location: (" + (sprite.getX()-camX) + ", " + (sprite.getY()-camY) + ")", sprite.getX()-camX, sprite.getY()-camY);
}
//Player location (center of Camera... Camera follows player)
g.setColor(Color.cyan);
g.fillRect(player.getX()-player.getWidth(), player.getY()-player.getWidth(), player.getWidth(), player.getHeight());
g.setColor(Color.white);
//World Sprite Location
g.drawString("World Sprite Location: (" + sprite.getX() + ", " + sprite.getY() + ")", sprite.getX(), sprite.getY());
//Cam Player Location
g.drawString("Cam Player Location: (" + (camW/2-player.getWidth()) + ", " + (camH/2-player.getHeight()) + ")", camW/2-player.getWidth(), camH/2-player.getHeight());
}
public void keyPressed(KeyEvent e) {
//move camera right in relation to World
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
camX+=5;
}
//move camera left in relation to World
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
camX-=5;
}
//move camera up in relation to World
if (e.getKeyCode() == KeyEvent.VK_UP) {
camY-=5;
}
//move camera down in relation to World
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
camY+=5;
}
repaint();
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
世界一流:
public class WorldSSCCE {
private int x, y, w, h;
private CameraSSCCE camera;
public WorldSSCCE(CameraSSCCE cam, int x, int y, int w, int h) {
camera = cam;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getWidth() {
return this.w;
}
public int getHeight() {
return this.h;
}
}
玩家等级:
import java.awt.Dimension;
public class PlayerSSCCE {
private int x, y, w, h;
private CameraSSCCE cam;
public PlayerSSCCE(CameraSSCCE cm, int x, int y, int w, int h) {
cam = cm;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getWidth() {
return this.w;
}
public int getHeight() {
return this.h;
}
public void setX(int val) {
this.x += val;
}
public void setY(int val) {
this.y += val;
}
}
精灵类:
import java.awt.Color;
import java.awt.Graphics;
public class SpriteSSCCE {
private int xLoc, yLoc, width, height;
private CameraSSCCE world;
public SpriteSSCCE(CameraSSCCE wld, int x, int y, int w, int h) {
xLoc = x;
yLoc = y;
width = w;
height = h;
world = wld;
}
public int getX() {
return xLoc;
}
public int getY() {
return yLoc;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void paintComponent(Graphics g) {
g.setColor(Color.green);
g.fillRect(xLoc, yLoc, width, height);
}
}