无法让精灵与地图图像碰撞(java)

时间:2017-10-23 21:41:38

标签: java

我正在创建一个2D游戏,僵尸用WASD键移动,并且应该与墙壁碰撞而不是进入它们,以及与大脑碰撞并移除它们。我使用的每种代码都不会产生冲突。我正在使用谷歌上发现的僵尸精灵表以及2个无墙图像的墙壁和大脑。

在我弄清楚碰撞之后,然后我实现了一个自动运行序列,它像屏幕保护程序一样反弹,并自动完成相同的操作,直到收集到所有大脑。

EZ只是一个由UH Manoa使用的图书馆,可以在这里找到:EZ Graphics

主要

import java.awt.Color;
import java.io.FileReader;
import java.util.Scanner;

public class ZombieMain {

    static EZImage[] walls = new EZImage[500];
    static EZImage[] sideWalls = new EZImage[500];
    static EZImage[] brains = new EZImage[50];
    static int wallsCount = 0;
    static int sideWallsCount = 0;
    static int brainsCount = 0;

    /*public static void addWall(EZImage wall) {
        walls[wallsCount] = wall;
        wallsCount++;
    }

    public static void addCoin(EZImage brain) {
        brains[brainsCount] = brain;
        brainsCount++;
    }*/

    /*public static void CollisingCoin(EZImage me) {

        int x = me.getXCenter();
        int y = me.getYCenter();
        for (int i = 0; i < brainsCount; i++) {
            if ((brains[i].isPointInElement(me.getXCenter() - 30, me.getYCenter() - 30))
                    || (brains[i].isPointInElement(me.getXCenter() + 30, me.getYCenter() - 30))
                    || (brains[i].isPointInElement(me.getXCenter() - 30, me.getYCenter() + 30))
                    || (brains[i].isPointInElement(me.getXCenter() + 30, me.getYCenter() + 30))) {
                brains[i].translateTo(-20, -20);
                System.out.println("You ate a brain!");
            }
        }
    }*/

    public static void main(String[] args) throws java.io.IOException {

        //initialize scanner
        Scanner fScanner = new Scanner(new FileReader("boundaries.txt"));

        int w = fScanner.nextInt();
        int h = fScanner.nextInt();
        String inputText = fScanner.nextLine();

        //create backdrop
        EZ.initialize(w*33,h*32);
        EZ.setBackgroundColor(new Color(0, 0,0));
        Zombie me = new Zombie("zombieSheet.png", 650, 450, 65, 63, 10);


        //set reading parameters and establish results of case readings
        int row = 0;

        while(fScanner.hasNext()) {

            inputText = fScanner.nextLine();

            for (int column = 0; column < inputText.length(); column++){

                char ch = inputText.charAt(column);

                switch(ch){
                case 'W':
                    walls[wallsCount] = EZ.addImage("barbwire.jpg", column*32, row*32);
                    wallsCount++;
                    break;      
                case 'M':
                    sideWalls[wallsCount] = EZ.addImage("barb.jpg", column*32, row*32);
                    wallsCount++;
                    break;
                case 'B':
                    brains[brainsCount] = EZ.addImage("brains.png", column*32, row*32);
                    brainsCount++;
                    break;
                default:
                    // Do nothing
                    break;

                }

                //printed count of walls, side walls, and brains
                System.out.println("W = " + wallsCount);
                System.out.println("M = " + sideWallsCount);
                System.out.println("B = " + brainsCount);

            }
            row++;
        }

        fScanner.close();

        while (true) {

            // check if going to collide with wall
            // we want to check this before we actually move
            // otherwise, we get "stuck" in a situation where we can't move
            // if no collision, we can move

            /*if (EZInteraction.isKeyDown('a')) {
                if (!isCollisingWall(me, -2, 0)) {
                    me.translateBy(-2, 0);
                }
            } else if (EZInteraction.isKeyDown('d')) {
                if (!isCollisingWall(me, 2, 0)) {
                    me.translateBy(2, 0);
                }
            } else if (EZInteraction.isKeyDown('w')) {
                if (!isCollisingWall(me, 0, -2)) {
                    me.translateBy(0, -2);
                }
            } else if (EZInteraction.isKeyDown('s')) {
                if (!isCollisingWall(me, 0, 2)) {
                    me.translateBy(0, 2);
                }
            }*/
            me.go();
            EZ.refreshScreen();
        }

    }

}

的Sprite

public class Zombie {

    EZImage zombieSheet;

    int x = 0;              // Position of Sprite
    int y = 0;
    int zombieWidth;        // Width of each sprite
    int zombieHeight;       // Height of each sprite
    int direction = 0;      // Direction character is walking in
    int walkSequence = 0;   // Walk sequence counter
    int cycleSteps;         // Number of steps before cycling to next animation step
    int counter = 0;        // Cycle counter


    Zombie(String imgFile, int startX, int startY, int width, int height, int steps) {
        x = startX;                 // position of the sprite character on the screen
        y = startY;
        zombieWidth = width;        // Width of the sprite character
        zombieHeight = height;      // Height of the sprite character
        cycleSteps = steps;         // How many pixel movement steps to move before changing the sprite graphic
        zombieSheet = EZ.addImage(imgFile, x, y);
        setImagePosition();
    }

    private void setImagePosition() {

        // Move the entire sprite sheet
        zombieSheet.translateTo(x, y);

        // Show only a portion of the sprite sheet.
        // Portion is determined by setFocus which takes 4 parameters:
        // The 1st two numbers is the top left hand corner of the focus region.
        // The 2nd two numbers is the bottom right hand corner of the focus region.
        zombieSheet.setFocus(walkSequence * zombieWidth, direction, walkSequence * zombieWidth + zombieWidth, direction + zombieHeight);
    }

    public void moveDown(int stepSize) {
        y = y + stepSize;

        direction = 0;

        if ((counter % cycleSteps) == 0) {
            walkSequence++;
            if (walkSequence > 6)
                walkSequence = 0;
        }
        counter++;
        setImagePosition();
    }

    public void moveLeft(int stepSize) {
        x = x - stepSize;
        direction = zombieHeight * 2;

        if ((counter % cycleSteps) == 0) {
            walkSequence--;
            if (walkSequence < 0)
                walkSequence = 6;
        }
        counter++;
        setImagePosition();
    }

    public void moveRight(int stepSize) {
        x = x + stepSize;
        direction = zombieHeight;

        if ((counter % cycleSteps) == 0) {
            walkSequence++;
            if (walkSequence > 6)
                walkSequence = 0;
        }
        counter++;

        setImagePosition();
    }

    public void moveUp(int stepSize) {
        y = y - stepSize;
        direction = zombieHeight * 3;

        if ((counter % cycleSteps) == 0) {
            walkSequence--;
            if (walkSequence < 0)
                walkSequence = 6;
        }
        setImagePosition();

        counter++;
    }


    // Keyboard controls for moving the character.
    public void go() {
        if (EZInteraction.isKeyDown('w')) {
            moveUp(2);
        } else if (EZInteraction.isKeyDown('a')) {
            moveLeft(2);
        } else if (EZInteraction.isKeyDown('s')) {
            moveDown(2);
        } else if (EZInteraction.isKeyDown('d')) {
            moveRight(2);
        }
    }

    public void translateBy(int i, int j) {
        // TODO Auto-generated method stub

    }

    public int getXCenter() {
        // TODO Auto-generated method stub
        return x;
    }

    public int getYCenter() {
        // TODO Auto-generated method stub
        return y;
    }

    public int getWidth() {
        // TODO Auto-generated method stub
        return 0;
    }

    public int getHeight() {
        // TODO Auto-generated method stub
        return 0;
    }



}

2 个答案:

答案 0 :(得分:1)

EZElement提供getBounds属性,返回java.awt.Shape个对象;为什么这很重要?因为Java 2D Graphics API已经提供了一些命中检测。

由此,我们需要确定玩家形状与任何其他形状的交集。为此,我们需要将两个形状包装在Area中并使用它来进行最终确定。

Area meArea = new Area(me.getBounds());
Area checkArea = new Area(elementToCheck.getBounds());
checkArea(meArea);
if (!checkArea.isEmpty()) {
    //... We have collision
}

显然,这应该用某种方法来处理核心功能,但你可以有一个辅助方法,它只需要两个EZElement并返回true / {{1如果碰撞

为了简洁和测试,我剥离了你的例子,但基本的想法应该继续工作

false

答案 1 :(得分:0)

我建议你给每个实体(和块/瓦片)一个碰撞盒,然后测试一个特定实体的边界框是否与另一个实体的边界框相撞,然后使它成为实体不能朝那个方向移动,直到方向上没有任何边界框,如果之后的话,那么实体就是这样。
为测试大脑做同样的事情,尽管我建议制作一个大脑的ArrayList,如果触摸了大脑,则删除特定的大脑。