Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Game Programming Part 1: Smooth Movement

Tags:

java

swing

pacman

I'm one third of a three member group in a computer class (high school freshmen). For our project we decided to make a Pac-Man style game in Java. None of us have much experience, so we've essentially been teaching ourselves up to this point. We've made quite a bit of progress, but we seem to have reached a standstill at this point. Here are our main questions:

  1. How can we make our Pacman (Fatman) move smoothly across the tiles? He moves tile by tile, but that looks unprofessional. In addition, when you hold down the arrow keys he zips across the screen. How can we prevent that from happening?

(I have other things I need help on but they are in different questions)

Thank you for your help!

Here is our code so far:

Maze Class:

package Fatman;

import javax.swing.*;

public class Maze {
    public static void main(String[] args){
        new Maze();
    }

    public Maze(){
        JFrame f = new JFrame();
        f.setTitle("Fatman!");
        f.add(new Board());
        f.setSize(816, 838);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Map Class

    package Fatman;

import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

public class Map {

    private Scanner m;
    private String Map[] = new String[25]; 

    private Image spaceregcandy,
                  srcb,
                  safehouse,
                  spacebigcandy,
                  blackspace,
                  space,
                  portal1,
                  portal2,
                  wall;

    public Map(){

        ImageIcon img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\spaceregcandy.png");
        spaceregcandy = img.getImage();
        //image icon has already been initiated, so it doesn't have to be written again
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\spaceregcandyblue.png");
        srcb = img.getImage();
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\safehouse.png");
        safehouse = img.getImage();
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\wall232x.png");
        wall = img.getImage();
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\spacebigcandy.png");
        spacebigcandy = img.getImage();
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\blackspace.png");
        blackspace = img.getImage();
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\space.png");
        space = img.getImage();
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\portal1.png");
        portal1 = img.getImage();
        img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\portal2.png");
        portal2 = img.getImage();

        openFile();
        readFile();
        closeFile();
        }

    public Image getSpaceregcandy(){
        return spaceregcandy;
    }
    public Image getSrcb(){
        return srcb;
    }
    public Image getSafehouse(){
        return safehouse;
    }
    public Image getWall(){
        return wall;
    }
    public Image getSpacebigcandy(){
        return spacebigcandy;
    }
    public Image getBlackspace(){
        return blackspace;
    }
    public Image getSpace(){
        return space;
    }
    public Image getPortal1(){
        return portal1;
    }
    public Image getPortal2(){
        return portal2;
    }

    public String getMap(int x, int y){
        String index = Map[y].substring(x, x + 1);
        return index;
        //in y position, if y = 2, goes to second row (substring gets x position)
    }

    public void openFile(){

        try{
        m = new Scanner(new File("C:\\Users\\Martin\\Desktop\\Fatman Project\\map3.txt"));
        }catch(Exception e){
            System.out.println("error loading map");
        }
    }

    public void readFile(){
        while(m.hasNext()){
            for(int i = 0; i < 25; i++){
                Map[i] = m.next();
            }
        }

    }

    public void closeFile(){
        m.close();
    }
}

Board Class

package Fatman;

import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.*;

public class Board extends JPanel implements ActionListener{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private Timer timer;

    private Image player;

    private Map m;
    private Player p;

    public Board(){

        m = new Map();
        p = new Player();
        addKeyListener(new Al());
        setFocusable(true);
        timer = new Timer(1, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e){
        repaint();

    }

    public void paint(Graphics g){
        super.paint(g);

        for(int y = 0; y < 25; y++){
            for(int x = 0; x <25; x++){
                if(m.getMap(x, y).equals("o")){
                    g.drawImage(m.getSpaceregcandy(), x *32, y *32, null);
                }
                if(m.getMap(x, y).equals("O")){
                    g.drawImage(m.getSrcb(), x *32, y *32, null);
                }
                if(m.getMap(x, y).equals("x")){
                    g.drawImage(m.getWall(), x *32, y *32, null);
                }
                if(m.getMap(x, y).equals("H")){
                    g.drawImage(m.getSafehouse(), x *32, y *32, null);
                }   
                if(m.getMap(x, y).equals("C")){
                    g.drawImage(m.getSpacebigcandy(), x *32, y *32, null);
                }
                if(m.getMap(x, y).equals("b")){
                    g.drawImage(m.getBlackspace(), x *32, y *32, null);
                }
                if(m.getMap(x, y).equals("s")){
                    g.drawImage(m.getSpace(), x *32, y *32, null);
                }
                if(m.getMap(x, y).equals("p")){
                    g.drawImage(m.getPortal1(), x *32, y *32, null);
                }
                if(m.getMap(x, y).equals("P")){
                    g.drawImage(m.getPortal2(), x *32, y *32, null);
                }
        }


    }


        g.drawImage(p.getPlayer(), p.getTileX() * 32, p.getTileY() * 32, null);

}

    public class Al extends KeyAdapter{

        public void keyPressed(KeyEvent e){
            int keycode = e.getKeyCode();

            if(keycode == KeyEvent.VK_UP){
                if(!m.getMap(p.getTileX(), p.getTileY() -1).equals("x")){
                    if(!m.getMap(p.getTileX(), p.getTileY() -1).equals("b")){                       
                        }
                        p.move(0, -1);                  

                        System.out.println(m.getMap(p.getTileX(), p.getTileY()));

            }
                }

            if(keycode == KeyEvent.VK_DOWN){
                if(!m.getMap(p.getTileX(), p.getTileY() +1).equals("x")){
                    if(!m.getMap(p.getTileX(), p.getTileY() +1).equals("b")){
                        p.move(0, 1);
                        System.out.println(m.getMap(p.getTileX(), p.getTileY()));
            }
                }
            }
            if(keycode == KeyEvent.VK_LEFT){
                if(!m.getMap(p.getTileX() - 1, p.getTileY()).equals("x")){
                    if(!m.getMap(p.getTileX() - 1, p.getTileY()).equals("b")){
                        p.move(-1, 0);
                        System.out.println(m.getMap(p.getTileX(), p.getTileY()));
            }
                }
            }
            if(keycode == KeyEvent.VK_RIGHT){
                if(!m.getMap(p.getTileX() + 1, p.getTileY()).equals("x")){
                    if(!m.getMap(p.getTileX() + 1, p.getTileY()).equals("b")){
                        p.move(1, 0);
                        System.out.println(m.getMap(p.getTileX(), p.getTileY()));
            }
            }
            }
            }


        public void keyReleased(KeyEvent e){

        }

        public void keyTyped(KeyEvent e){

}
}
}

Player Class

package Fatman;

import java.awt.Image;

import javax.swing.ImageIcon;

public class Player {

    private int tileX, tileY;
    private int dx, dy;

    private Image player; 

    public Player(){

        ImageIcon img = new ImageIcon("C:\\Users\\Martin\\Desktop\\Fatman Project\\FATMANsimplified32xbrown.png");
        player = img.getImage();

        tileX = 12;
        tileY = 18;
    }

    public Image getPlayer(){
        return player;
    }
    public int getTileX(){
        return tileX;
    }
    public int getTileY(){
        return tileY;
    }

    public void move(int dx, int dy){

        tileX += dx;
        tileY += dy;
    }

}

Any ideas?

like image 390
leo882 Avatar asked Nov 27 '25 16:11

leo882


1 Answers

Well for your first question, recognize that you're just incrementing the tile numbers in your move method, and later on repainting the player at that location (with an increment of 32 pixels). You need finer level of granularity than that, that is incrementing not by tiles themselves, but by portion of tiles (e.g. by 2 pixels). So that FatMan's image would take more steps to move from 1 tile to another. Obviously it would look even better if FatMan's image player a walking/running animation during that time, to make movement seem more natural.

So... in shameless self promotion I invite you to take a look at my old tutorial here: https://sites.google.com/site/javagamescorner/home/animated-sprites

like image 58
Evgheni Crujcov Avatar answered Nov 30 '25 06:11

Evgheni Crujcov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!