我正在为我的一个类似于Java游戏“Fishy”的类开发Android游戏。玩家吃较小的鱼并长大,但如果与较大的鱼接触则被吃掉。我一直在使用James Cho的“Android开发指南”中的框架来创建游戏,但碰撞检测没有注册。在游戏和指南中,模型被放入数组列表中,并在屏幕上显示,如果可见,更新方法将检查碰撞。过去几天我一直在努力解决这个问题,同时试图找出究竟出了什么问题,但却没有提出任何问题。我看到的唯一效果就是在if(b.isVisible())之前进行碰撞检查,这导致玩家模型增长并从屏幕上掉下来。我一直试图比较有效的代码,矩形应该是它们应该在的位置。在应用程序中,游戏循环调用游戏状态,我将发布我的PlayState,Player和Predator代码。非常感谢任何建议或意见。
Playstate:
public class PlayState extends State {
private Player player;
private ArrayList<Predator> predators;
private Background bgRock1, bgRock2, bgHills1, bgHills2;
private int playerScore = 0;
private int playerWidth = 50;
private int playerHeight = 30;
private int predatorSpeed = -150;
private float recentTouchX;
@Override
public void init() {
player = new Player(GameMainActivity.GAME_WIDTH / 2, GameMainActivity.GAME_HEIGHT / 2,
playerWidth, playerHeight);
predators = new ArrayList<Predator>();
bgRock1 = new Background(GameMainActivity.GAME_WIDTH,
GameMainActivity.GAME_HEIGHT - (GameMainActivity.GAME_HEIGHT / 4), -100);
bgRock2 = new Background(0, GameMainActivity.GAME_HEIGHT - (GameMainActivity.GAME_HEIGHT / 4),
-100);
bgHills1 = new Background(GameMainActivity.GAME_WIDTH,
GameMainActivity.GAME_HEIGHT - (GameMainActivity.GAME_HEIGHT / 2) - 10, -20);
bgHills2 = new Background(0, GameMainActivity.GAME_HEIGHT - (GameMainActivity.GAME_HEIGHT / 2) - 10,
-20);
for(int i = 0; i < 10; i++){
//Predator b = new Predator(i * 200, GameMainActivity.GAME_HEIGHT - 95, PREDATOR_WIDTH,
//PREDATOR_HEIGHT);
Predator b = new Predator();
predators.add(b);
}
}
@Override
public void update(float delta) {
if(!player.isAlive()){
setCurrentState(new GameOverState(playerScore / 100));
}
playerScore += 1;
if(playerScore % 500 == 0 && predatorSpeed > -280){
predatorSpeed -= 10;
}
//Update positions
//Add background here
bgHills1.update(delta);
bgHills2.update(delta);
bgRock1.update(delta);
bgRock2.update(delta);
Assets.swimAnim.update(delta);
Assets.rSwimAnim.update(delta);
player.update(delta);
Assets.predatorSwimAnim.update(delta);
Assets.predatorSwimAnim2.update(delta);
Assets.predatorSwimAnim3.update(delta);
Assets.predatorSwimAnim4.update(delta);
updatePredators(delta);
}
private void updatePredators(float delta){
for(Predator b : predators) {
b.update(delta, predatorSpeed);
if(b.isVisible()){ //COLLISION DETECTION
if(Rect.intersects(b.getRect(), player.getRect())){
b.setVisible(false);
playerWidth *= 5;
playerHeight = (int) (playerWidth * 0.6);
//player.setIsAlive(false);
}
}
}
}
@Override
public void render(Painter g) {
//g.drawimage background, filler right now
g.setColor(Color.rgb(208, 244, 247));
g.fillRect(0, 0, GameMainActivity.GAME_WIDTH, GameMainActivity.GAME_HEIGHT);
renderBackground(g);
renderPlayer(g);
renderPredators(g);
renderScore(g);
}
private void renderScore(Painter g){
g.setFont(Typeface.SANS_SERIF, 25);
g.setColor(Color.GRAY);
g.drawString("" + playerScore / 100, 20, 30);
}
private void renderPlayer(Painter g){
//get image to reflect horizontally w/ isMovingLeft()
if(!player.isMovingLeft) {
Assets.swimAnim.render(g, (int) player.getX(), (int) player.getY(),
(int) player.getWidth(), (int) player.getHeight());
} else {
Assets.rSwimAnim.render(g, (int) player.getX(), (int) player.getY(),
(int) player.getWidth(), (int) player.getHeight());
}
}
private void renderPredators(Painter g){
for(Predator b : predators){
if(b.isVisible()){
switch(b.getType()){
case 1:
Assets.predatorSwimAnim.render(g, (int) b.getX(), (int) b.getY(), b.getWidth(),
b.getHeight());
break;
case 2:
Assets.predatorSwimAnim2.render(g, (int) b.getX(), (int) b.getY(), b.getWidth(),
b.getHeight());
break;
case 3:
Assets.predatorSwimAnim3.render(g, (int) b.getX(), (int) b.getY(), b.getWidth(),
b.getHeight());
break;
case 4:
Assets.predatorSwimAnim4.render(g, (int) b.getX(), (int) b.getY(), b.getWidth(),
b.getHeight());
break;
}
}
}
}
public void renderBackground(Painter g){
g.drawImage(Assets.hills1, (int) bgHills1.getX(), (int) bgHills1.getY(),
GameMainActivity.GAME_WIDTH, GameMainActivity.GAME_HEIGHT / 2);
g.drawImage(Assets.hills1, (int) bgHills2.getX(), (int) bgHills2.getY(),
GameMainActivity.GAME_WIDTH, GameMainActivity.GAME_HEIGHT / 2);
g.drawImage(Assets.rock2, (int) bgRock1.getX(),
(int) bgRock1.getY(), GameMainActivity.GAME_WIDTH,
GameMainActivity.GAME_HEIGHT / 3);
g.drawImage(Assets.rock2, (int) bgRock2.getX(), (int) bgRock2.getY(),
GameMainActivity.GAME_WIDTH, GameMainActivity.GAME_HEIGHT / 3);
//Create new Model class for backgroundItem
}
@Override
public boolean onTouch(MotionEvent e, int scaledX, int scaledY) {
if(e.getAction() == MotionEvent.ACTION_DOWN){
recentTouchX = scaledX;
} else if(scaledX - recentTouchX < 0){
player.setIsMovingLeft(true);
} else {
player.setIsMovingLeft(false);
}
player.setX(scaledX - 90); //make offset constants
player.setY(scaledY - 90);
return true;
}
}
捕食者类:
public class Predator {
private float x, y;
private int width;
private int height;
private int type;
private Rect rect;
private boolean visible;
public Predator(){
x = RandomNumberGenerator.getRandIntBetween(GameMainActivity.GAME_WIDTH,
GameMainActivity.GAME_WIDTH + 500);
y = RandomNumberGenerator.getRandIntBetween(20, GameMainActivity.GAME_HEIGHT);
width = RandomNumberGenerator.getRandIntBetween(10, 100);
height = (int) (width * 0.6);
rect = new Rect((int) x, (int) y, (int) x + width, (int) y + height);
visible = false;
type = RandomNumberGenerator.getRandIntBetween(0,5);
}
public Predator(float x, float y, int width, int height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
rect = new Rect((int) x, (int) y, (int) x + width, (int) y + height);
visible = false;
type = RandomNumberGenerator.getRandIntBetween(0,5);
}
public void update(float delta, float velX){
x += velX * delta;
if(x <= -100){
reset();//double check
}
}
public void updateRect(){
rect.set((int) x, (int) y, (int) x + width, (int) y + height);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Rect getRect() {
return rect;
}
public int getType() {
return type;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public boolean isVisible() {
return visible;
}
public void reset(){
visible = true;
y = RandomNumberGenerator.getRandIntBetween(20, GameMainActivity.GAME_HEIGHT);
x += 1000;
updateRect();
}
public void onCollide(Player p){ //Collision event
if(rect.width() < p.getWidth()) {
visible = false;
p.setWidth((int) (p.getWidth() * 1.2));
p.setHeight((int) (p.getHeight() * 1.2));
} else{
p.setIsAlive(false);
}
}
}
播放器:
public class Player {
private float x, y;
private int width, height;
private Rect rect;
private boolean isAlive;
public boolean isMovingLeft;
public void setIsMovingLeft(boolean isMovingLeft) {
this.isMovingLeft = isMovingLeft;
}
public Player(float x, float y, int width, int height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
rect = new Rect();
isAlive = true;
isMovingLeft = false;
}
public void update(float delta){
updateRects();
}
public void updateRects() {
rect.set((int) x, (int) y, (int) x + width, (int) y + height);
}
public void grow() { //growth event
width *= 1.2;
height *= 1.2;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
public Rect getRect() {
return rect;
}
public boolean isMovingLeft() {
return isMovingLeft;
}
public boolean isAlive() {
return isAlive;
}
public void setY(float y) {
this.y = y;
}
public void setX(float x) {
this.x = x;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public void setIsAlive(boolean isAlive) {
this.isAlive = isAlive;
}
}
请记住这是我的第一篇文章,所以如果我做错了(比如发布过多代码),请告诉我以供将来参考。感谢大家!