精灵运动/动画

时间:2012-02-02 00:45:56

标签: java image animation sprite

我现在非常紧张(拖延,zzz),所以非常感谢任何帮助!

我现在有一个项目涉及创建一个顶级的2D RPG,不一定要大,只是一个小型的常见RPG元素。

虽然我不是很远,但我有目标和时间表可以见面,所以在这方面,我目前正在使用精灵和动画。

首先,我的游戏是在2D阵列系统中构建的,这在我自上而下的RPG中看起来非常合理。无论如何,我发现了一个看似合适的Sprite类供在线使用,在我的游戏中,我正在尝试制作两个动画/工作的东西。我的主角和火球。火球本质上是他的咒语 - 在我的脑海里,我想看到的是,当我按下键盘上的按钮时,火球应该“生成”或者在角色的位置被绘制(这是我到目前为止所有D:大声笑)然后继续朝着角色面对的方向前进。

所以,这就是火球。至于主角,我总共有八个图像,每个方向的步行动画由两个图像表示。这是一张图片(spritesheet),我已经导入到我的项目中,并且能够使用BufferedImage中的getSubimage()进行分离。

事情是......我有点被困在这里。我不确定我应该如何让火球开始朝着角色所朝的方向前进(我假设它与速度有关,但我对浮子也有点无能为力......我对它们进行了类型化处理为了简单起见lol)。

同样,我不确定每次按下向上箭头键时,我应该如何顺利播放两个用于方向行走动画的图像。

只是不理解动画!我几乎阅读了所有内容,但由于截止日期我仍然感到困惑和压力(很快,如果你知道我的意思)。

我会发布一些代码,不确定你们是否需要更多代码,但我会站在那里!

再一次,非常感谢我得到的任何帮助,非常感谢!

P.S。我是初学者,所以我的代码对大多数人来说一定非常混乱,但我想这会随着时间而来

ArrayList<TreeMonster> treeMonsters = new ArrayList<TreeMonster>();
ArrayList<Fireball> qProjectiles = new ArrayList<Fireball>();
private Timer timer;

private void toggleKey(int keyCode, boolean pressed){
if (keyCode == KeyEvent.VK_Q){
        qProjectiles.add(new Fireball(vlad.getXLoc(), vlad.getYLoc(), vlad.getDirection(), vlad.getLevel()*10));
    }
}

// Entities are spawned on the map
public void spawnOnMap(Matter[][] map){

    map[1][1] = new Matter(1, 1, 1);
    vlad.moveTo(1,1);
    map[4][4] = new Matter(3, 4, 4);
    treeMonsters.add(new TreeMonster(4, 4));
    map[4][7] = new Matter(3, 4, 7);
    treeMonsters.add(new TreeMonster(4, 7));
    map[8][2] = new Matter(3, 8, 2);
    treeMonsters.add(new TreeMonster(8, 2));
    map[8][8] = new Matter(3, 8, 8);
    treeMonsters.add(new TreeMonster(8, 8));
    map[12][3] = new Matter(3, 12, 3);
    treeMonsters.add(new TreeMonster(12, 3));
    map[12][9] = new Matter(3, 12, 9);
    treeMonsters.add(new TreeMonster(12, 9));
    map[14][6] = new Matter(3, 14, 6);
    treeMonsters.add(new TreeMonster(14, 6));
    map[16][10] = new Matter(3, 16, 10);
    treeMonsters.add(new TreeMonster(16, 10));
    map[19][5] = new Matter(3, 19, 5);
    treeMonsters.add(new TreeMonster(19, 5));
    map[2][1] = new Matter(2, 2, 1);
    npcOne.moveTo(2, 1);
}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    while (vlad.living()){

        Graphics g2d = (Graphics2D)g;
        g2d.drawImage(desertMap,0,0,this);
        for (int i = 0; i < treeMonsters.size(); i++){
            g2d.drawImage(treeMonsters.get(i).tree, treeMonsters.get(i).getXLoc()*64, treeMonsters.get(i).getYLoc()*64, this);
        }

        for (int i = 0; i < qProjectiles.size(); i++){
            g2d.drawImage(qProjectiles.get(i).fBallSprite.getImage(), qProjectiles.get(i).xLoc()*64, qProjectiles.get(i).yLoc()*64, this);
            if (vlad.getDirection() == 0){
                qProjectiles.get(i).fBallSprite.setVelocityY(0.2f);
            }   
            if (vlad.getDirection() == 1){
                qProjectiles.get(i).fBallSprite.setVelocityY(-0.2f);
            }

            if (vlad.getDirection() == 2){
                qProjectiles.get(i).fBallSprite.setVelocityX(-0.2f);
            }

            if (vlad.getDirection() == 3){
                qProjectiles.get(i).fBallSprite.setVelocityX(0.2f);
            }
        }

        if (vlad.disableFirst){
            g2d.drawImage(vlad.getDirectionImage(), vlad.getXLoc()*64, vlad.getYLoc()*64, this);
        }
        else{
            if (vlad.getDirection() == 0){
                vlad.upWalk.update(System.currentTimeMillis());
                g2d.drawImage(vlad.upWalk.sprite, vlad.getXLoc()*64, vlad.getYLoc()*64, this);
            }
            else if (vlad.getDirection() == 1){
                vlad.downWalk.update(System.currentTimeMillis());
                g2d.drawImage(vlad.downWalk.sprite, vlad.getXLoc()*64, vlad.getYLoc()*64, this);
            }
            else if (vlad.getDirection() == 2) {
                vlad.leftWalk.update(System.currentTimeMillis());
                g2d.drawImage(vlad.leftWalk.sprite, vlad.getXLoc()*64, vlad.getYLoc()*64, this);
            }
            else if (vlad.getDirection() == 3){
                vlad.rightWalk.update(System.currentTimeMillis());
                g2d.drawImage(vlad.rightWalk.sprite, vlad.getXLoc()*64, vlad.getYLoc()*64, this);
            }
        }

        g2d.drawImage(npcOne.getImage(), 2*64, 1*64, this);
   }
}

2 个答案:

答案 0 :(得分:0)

这里有点伪装:

if(walking north button pressed) {
    play walkNorth animation;
    direction = "north";
} else if(walking east button pressed) {
    play walkEast animation;
    direction = "east";
} else if(walking south button pressed) {
    play walkSouth animation;
    direction = "south";
} else if(walking west button pressed) {
    play walkWest animation;
    direction = "west";
}

我不知道你是否设置了这样的角色移动,但重要的是根据移动的最后方向跟踪方向面(对角线只有else if个。{Now}如果你有方向,可以像这样制作火球:

instantiate fireball;
fireball's x = player's x;
fireball's y = player's y;
send direction to fireball instance;

然后你会希望它执行每一帧:

if(this.direction=="north") {
    this.y -= speed;
} else if(this.direction=="east") {
    this.x += speed;
} else if(this.direction=="south") {
    this.y += speed;
} else if(this.direction=="west") {
    this.x -= speed;
}

注意:假设x增加了左边,y增加了。

答案 1 :(得分:0)

我的第一印象 - 没有运行代码就是你需要设置paintComponent的游戏循环--outside。 paintComponent只应包含渲染所需的代码,而不包含任何其他代码。因此,您需要构建代码以获得更好的游戏循环。是的,你正在做的所有内容(vladLives)你在paintComponent中。阅读“如何设置Java游戏循环”下的一些教程,以便更好地理解。

http://www.java-gaming.org/index.php/topic,24220.0

以上将是一个良好的开端。基本上我给你的建议是建立一个叫做Main的课程。这将是你的游戏入口点并将保持'public static void main ....'在这个类中编写gameLoop并调用你的动画类来移动你的数字。

我希望我有更多时间保持清醒。你有几件事很重要。你想要一个Timer,你想为每个定时器'tick'调用你的渲染函数。但是将所有游戏逻辑保留在paintComponent之外。理想情况下,将它全部保存在Main中。

再一次,抱歉目前不能给你完整的例子,但是接受我所说的并研究本教程中的示例代码,它应该对你来说非常清楚。

相关问题