0
votes

I'm pretty tight on time right now (procrastination, zzz), so would greatly appreciate any help!

I have a project at the moment which involves creating a top dimensional 2D RPG, doesn't have to be big, just a small representation of common RPG elements.

While I'm not extremely far, I have goals and timelines to meet, so in that regard, I'm currently working with sprites and animation.

First off, my game is built in a 2D array system, which seemed pretty reasonable to me in a top down RPG. Anyway, I found a seemingly suitable Sprite class for use online and in my game, I'm trying to make two things animated/work. My main character and a fireball. The fireball is essentially his spell - in my mind, what I want to see, is when I press a button on my keyboard, the fireball should "spawn" or be drawn at the character's location (this is all I have so far D: lol) and then continue going straight in the direction the character is facing.

So, that's for the fireball. As for the main character, I have a total of eight images, with each direction's walking animation represented by two images. This is all in one picture (spritesheet), which I have imported into my project and have been able to separate using getSubimage() from BufferedImage.

The thing is.. I'm kind of stuck here. I'm not sure how I should have the fireball start going straight in the direction the character is facing (I'm assuming it has something to do with the velocity, but I'm also kind of clueless at floats.. I typecast them to ints for simplicity lol).

In the same regard, I'm not sure how I should smoothly have the character playback the two images meant for a direction's walking animation for each time the UP arrow key is pressed.

Just not understanding animation! I've read almost everything, but I'm still kind of confused and stressed due to the deadline (VERY soon, if you know what I mean).

I'll post some of my code, not sure if you guys will need more, but I'm standing by!

Once again, I greatly appreciate any help I get, thanks a lot!

p.s. I'm a beginner, so my code must be very messy to most, but I suppose that will come with time

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
tutorialized.com/tutorial/Animated-Sprites-in-Java/73560 Also a good game development book will save you hours. Killer Game Programming in Java by David Croft would be perfect. - Marc H

2 Answers

0
votes

Here a little psuedo:

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";
}

I don't know if you have character movement set up like this, but the important thing is to keep track of the direction face based on the last direction moved (just and more else ifs for diagonals. Now that you have your direction, you can create the fireball like this:

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

Then you will want this to execute every frame:

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;
}

Note: This is assuming x increases left and y increases down.

0
votes

My first impression - without running the code is that you will need to set up a game loop --outside-- of paintComponent. paintComponent should contain ONLY the code you need for rendering and nothing else. So you'll need to structure your code to have a better game loop. Yeah, you're doing everything inside that while(vladLives) you got in paintComponent. Read some tutorials under "How to set up a Java Game Loop" to gain a better understanding.

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

The above would be a good start. Basically my advice to you is set up a class called Main. This will be your games entry point and will hold 'public static void main...." Code the gameLoop inside this class and call your animation class to move your figures.

I wish I had more time to be crystal clear. It's important that you have several things. You want a Timer and you want to call your rendering function once for every timer 'tick'. But keep all the game logic outside paintComponent. Ideally, keep it all in Main.

Again, sorry can't give you full example at the moment but take what I've said and study the sample code in this tutorial and it should become crystal clear for you.