我在java游戏编程方面很开心,而且我对游戏有一个小问题(对我而言)。 我正在尝试在敌人和街区之间进行碰撞它不起作用,我不知道为什么。它应该工作,但它只是以每秒一个fps的速度减慢游戏并且不做任何事情。
我有一个名为Game的主类 使用这个主要的Init()函数
public void init(){
WIDTH = getWidth();
HEIGHT = getHeight();
tex = new Texture();
BufferImageLoader loader = new BufferImageLoader();
level = loader.loadImage("/level.png"); // loading level
cloud = loader.loadImage("/cloud.png"); // loading clouds
handler = new Handler();
cam = new Camera(0,0);
LoadImageLevel(level);
this.addKeyListener(new KeyInput(handler));
}
而不是LoadImageLevel函数,我逐个像素地读取level.png,并通过不同的颜色我设置每个对象的位置。
private void LoadImageLevel (BufferedImage image){
int w = image.getWidth();
int h = image.getHeight();
//System.out.println(w + " , " + h);
for(int xx = 0; xx < h; xx++){
for(int yy = 0; yy < w ; yy++){
int pixel = image.getRGB(xx, yy);
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
if(red == 255 && green == 255 && blue == 255)
handler.addObject(new Block(xx*32,yy*32,1,ObjectId.Block));
if(red == 0 && green == 0 && blue == 255)
handler.addObject(new Player(xx*32,yy*32,1,handler,ObjectId.Player));
if(red == 0 && green == 255 && blue == 0)
handler.addObject(new Enemy(xx*32,yy*32,handler,ObjectId.Enemy));
}
}
}
在类中,Player是两个重要的函数tick和collision,其中tick是被称为collison。
public class Player extends GameObject{
private float width = 32, // 48
height = 64; // 96
private float gravity = 0.5f;
private final float MAX_SPEED = 10;
private int facing = 1;
private int last = 0; // last position left or right
private Handler handler;
Texture tex = Game.getInstance();
private int type;
private Animation playerWalk, playerWalkLeft,jump;
public Player(float x, float y,int type , Handler handler ,ObjectId id) {
super(x, y, id);
this.handler = handler;
this.type = type;
playerWalk = new Animation(2,tex.player[2],tex.player[3],
tex.player[4],tex.player[5]);
playerWalkLeft = new Animation(2,tex.player[7],tex.player[8],
tex.player[9],tex.player[10]);
jump = new Animation(2,tex.player[11],tex.player[12]);
}
public void tick(LinkedList<GameObject> object) {
x += velX;
y += velY;
if(velX < 0) facing = -1;
else if(velX > 0) facing = 1;
if(falling || jumping){
velY += gravity;
if(velY > MAX_SPEED){
velY = MAX_SPEED;
}
}
Collision(object);
//System.out.println(velX + " " + velY);
playerWalk.runAnimation();
playerWalkLeft.runAnimation();
jump.runAnimation();
}
private void Collision(LinkedList<GameObject> object){
for(int i = 0; i < handler.object.size();i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ObjectId.Block ){
if(getBoundsTop().intersects(tempObject.getBounds())){
y = tempObject.getY() + 32;
velY = 0;
}
if(getBounds().intersects(tempObject.getBounds())){
y = tempObject.getY() - height;
velY = 0;
falling = false;
jumping = false;
}else
falling = true;
if(getBoundsRight().intersects(tempObject.getBounds())){
x = tempObject.getX() - width;
}
if(getBoundsLeft().intersects(tempObject.getBounds())){
x = tempObject.getX() + 35;
}
}
/* new */
}
}
public void render(Graphics g) {
/*
g.setColor(Color.blue);
g.fillRect((int)x,(int)y,(int)width,(int)height);
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.red);
g2d.draw(getBounds());
g2d.draw(getBoundsRight());
g2d.draw(getBoundsLeft());
g2d.draw(getBoundsTop());
*/
if(velX != 0){
if (facing == 1){
playerWalk.drawAnimation(g,(int) x, (int)y,32,64);
last = 1;
}
else{
playerWalkLeft.drawAnimation(g,(int) x, (int)y,32,64);
last = 0;
}
}
else
if (last == 1)
g.drawImage(tex.player[1], (int)x,(int) y,32,64,null);
else
g.drawImage(tex.player[6], (int)x,(int) y,32,64,null); // 6 ,32,64
//System.out.println("Y: " + y); // 513 je max
if (y >= 513){
g.setColor(Color.red);
g.drawString("Game Over", (int) x, 200);
}
}
public Rectangle getBounds() {
return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int) ((int)y+(height/2)),(int)width/2,(int)height/2);
}
public Rectangle getBoundsTop() {
return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int)y,(int)width/2,(int)height/2);
}
public Rectangle getBoundsRight() {
return new Rectangle((int) ((int)x+width-5),(int)y+5,(int)5,(int)height-10);
}
public Rectangle getBoundsLeft() {
return new Rectangle((int)x,(int)y+5,(int)5,(int)height-10);
}
玩家不会遇到块碰撞问题。
public class Block extends GameObject {
Texture tex = Game.getInstance();
private int type;
public Block(float x, float y,int type,ObjectId id) {
super(x, y, id);
this.type = type;
}
public void tick(LinkedList<GameObject> object) {
}
public void render(Graphics g) {
if(type == 0)
g.drawImage(tex.block[0], (int) x, (int) y ,null);
if(type == 1)
g.drawImage(tex.block[1], (int) x, (int) y ,null);
}
public Rectangle getBounds() {
return new Rectangle((int)x,(int)y,32,32);
}
}
但是,当我尝试创建Enemy类并使它像Player类中一样时,我的意思是碰撞它只会让游戏更慢而没有别的。
public class Enemy extends GameObject{
private Handler handler;
public Enemy(float x, float y,Handler handler, ObjectId id) {
super(x, y, id);
this.handler = handler;
}
public void tick(LinkedList<GameObject> object) {
for(int i = 0; i < handler.object.size();i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ObjectId.Block ){
if(getBoundsTop().intersects(tempObject.getBounds())){
}
if(getBounds().intersects(tempObject.getBounds())){
}
if(getBoundsRight().intersects(tempObject.getBounds())){
}
if(getBoundsLeft().intersects(tempObject.getBounds())){
}
}
}
}
public void render(Graphics g) {
g.setColor(Color.red);
g.fillRect((int)x,(int) y, 32, 32);
}
public Rectangle getBoundsTop() {
return new Rectangle((int)x,(int)y,32,32);
}
public Rectangle getBoundsLeft() {
return new Rectangle((int)x,(int)y,32,32);
}
public Rectangle getBoundsRight() {
return new Rectangle((int)x,(int)y,32,32);
}
public Rectangle getBounds() {
return new Rectangle((int)x,(int)y,32,32);
}}
我知道边界不应该返回相同的“新矩形”,并且当我设置勾选方法x--时,没有任何敌人的移动;只是尝试如果敌人停在它到达阻止的边缘,但它不起作用我不知道什么是错的,我花了两天以上来解决这个问题。如果它可以帮助你有一个整个项目的链接(Eclipse)You can download it from dropbox
我只是想让一个左右移动的敌人与阻挡相撞,这意味着当他从左侧“触碰”到他“转身”并向右移动直到他“触碰”时他的右侧等......玩家和敌人之间的其他碰撞对我来说不是问题。但就是这样。 我非常感谢每一条建议:)
答案 0 :(得分:0)
问题在于您的getBounds()
方法。
您在getBounds()
方法中说要返回包含width=32
和height=32
的矩形。由于您的矩形是32乘32(如fillrect(x,y,32,32)
中所述),因此getBounds()
返回高度和宽度的交点。
换句话说,尽量不要将返回的左上角或右边界与自己碰撞。
在enemy()
中,您在加载时声明set.color = red
您正在使用green
。请尝试使用red==255, green==0, blue==0
代替if(red == 0 && green == 255 && blue == 0)