I’m trying to make a Mario clone, and I can make sprites move with a keyListener, but I want to make sprites animate as they move. When the sprite moves, I want this:
https://i.stack.imgur.com/e9SuM.png
it starts as the left one, and when I hit the move right key, it shows the middle, and when it gets to the right, is the one on the right.
[![the middle sprite is shown once the move right button is hit, and it finishes when then sprite is two pixels right and goes back to original][1]][1]
So far, I have:
I’m trying to animate the sprite in my game when a button is pressed, but when I press the button, it skips the animation. Its supposed to go one pixel, change sprites, and then go one more pixel and change back. Here is the code
//for all
import java.nio.file.*;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.image.*;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import static java.lang.invoke.MethodHandles.*;
import java.awt.event.*;
//my Mario class (cut down a lot)
class Mario {
// all numbers multiplied by 2 from OG game
protected Direction dir;
protected int x, y;
protected BufferedImage sprite;
protected String currentSpriteName;
public Mario() {
this.x = 54;
this.y = 808;
dir = Direction.RIGHT;
setSprite(MVCE.SMALLSTANDFACERIGHT);
currentSpriteName = MVCE.SMALLSTANDFACERIGHT;
}
public void moveRight(){
if(this.dir == Direction.LEFT){
this.dir = Direction.RIGHT;
}
else if(this.dir == Direction.RIGHT){
this.x+=2;
}
}
public void jump() {
this.y -= 46;
}
public void setSprite(String spriteName) {
URL spriteAtLoc = MVCE.urlGenerator(spriteName);
this.sprite = MVCE.generateAndFilter(sprite, spriteAtLoc);
}
public void getSprite(){
System.out.println(this.currentSpriteName);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(sprite, 0, 0, null); // DO NOT SET x and y TO ANYTHING,
// this sets 0,0 to top left!!
}
}
<?– –>
// my MarioRender class:
public class MarioRender extends JLabel{
protected Mario marioSprite;
public MarioRender(){
marioSprite = new Mario();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
marioSprite.paint(g2);
setBounds(marioSprite.x, marioSprite.y, marioSprite.sprite.getWidth(), marioSprite.sprite.getHeight());
}
public void moveMarioRight(){
marioSprite.moveRight();
marioSprite.setSprite(MVCE.SMALLSTANDFACERIGHT);
setLocation(this.marioSprite.x, this.marioSprite.y);
repaint();
}
public void jumpMario(){
marioSprite.jump();
marioSprite.setSprite(MVCE.SMALLJUMPFACERIGHT);
setLocation(this.marioSprite.x, this.marioSprite.y);
repaint();
}
}
<?– –>
// direction class, solely for moving
enum Direction {
LEFT, RIGHT
}
<?– –>
// my calling class, which I called MVCE where I make the frame
public class MVCE extends JFrame{
MarioRender m = new MarioRender();
JLabel bg;
public MVCE(){
bg = new JLabel();
this.setSize(868, 915);
this.setVisible(true);
this.add(bg, BorderLayout.CENTER);
bg.setLayout(null);
bg.add(m);
m.setBounds(m.marioSprite.x, m.marioSprite.y, m.marioSprite.sprite.getWidth(), m.marioSprite.sprite.getHeight());
KeyListener kl = new MoveListener();
this.addKeyListener(kl);
this.setFocusable(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static final String SMALLSTANDFACERIGHT = “SmallStandFaceRight.bmp”; //30 x 32
public static final String SMALLJUMPFACERIGHT = “SmallJumpFaceRight.bmp”; //32 x 32
public static final String SMALLWALKFACERIGHT = “SmallWalkFaceRight.bmp”;
//generate URL
public static URL urlGenerator(String name){
URL u = lookup().lookupClass().getResource(name);
return u;
}
//return image with filtered color
public static BufferedImage generateAndFilter(BufferedImage b, URL u){
try{
b = ImageIO.read(u);
int width = b.getWidth();
int height = b.getHeight();
int[] pixels = new int[width * height];
b.getRGB(0, 0, width, height, pixels, 0, width);
for (int i = 0; i < pixels.length; i++) {
//System.out.println(pixels[i]);
if (pixels[i] == 0xFFff00fe) {
pixels[i] = 0x00ff00fe;
}
}
BufferedImage newSprite = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
newSprite.setRGB(0, 0, width, height, pixels, 0, width);
b = newSprite;
}
catch(IOException e){
System.out.println(“sprite not found”);
e.printStackTrace();
}
return b;
}
//key listener
class MoveListener implements KeyListener{
public void keyPressed(KeyEvent k){
if((k.getKeyCode() == 39)){
m.moveMarioRight();
m.marioSprite.getSprite();
System.out.println(m.marioSprite.getCoordinates());
}
if(k.getKeyCode() == 83){ //S key
m.jumpMario();
m.marioSprite.getSprite();
System.out.println(m.marioSprite.getCoordinates());
}
}
public void keyReleased(KeyEvent k){}
public void keyTyped(KeyEvent k){}
}
public static void main(String[] args){
MVCE m = new MVCE();
}
}
in my game, each sprite is its own file. I will not, under any circumstance, use a sprite sheet.
Expert Answer
Try adding this code to your above program.Hope it will run well.
MovingSprites.java
import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
public class MovingSprites {
private int x-co;
private int y-co;
private int x;
private int y;
private Image images;
public MovingSprites() {
initSprite();
}
private void initSprite() {
ImageIcon img = new ImageIcon(“MovingSprites.png”);
images = img.gettingImages();
x = 40;
y = 60;
}
public void moving() {
x += x-co;
y += y-co;
}
public int getXco() {
return x;
}
public int getYco() {
return y;
}
public Image gettingImages() {
return images;
}
public void keyPressed(KeyEvent e) {
int keyss = e.getKeyCode();
if (keyss == KeyEvent.VK_LEFT) {
x-co = -1;
}
if (keyss == KeyEvent.VK_RIGHT) {
x-co = 1;
}
if (keyss == KeyEvent.VK_UP) {
y-co = -1;
}
if (keyss == KeyEvent.VK_DOWN) {
y-co = 1;
}
}
public void keyReleased(KeyEvent e) {
int keyss = e.getKeyCode();
if (keyss == KeyEvent.VK_LEFT) {
x-co = 0;
}
if (keyss == KeyEvent.VK_RIGHT) {
x-co = 0;
}
if (keyss == KeyEvent.VK_UP) {
y-co = 0;
}
if (keyss == KeyEvent.VK_DOWN) {
y-co = 0;
}
}
}