Java游戏《超级玛丽》 swing界面

版权声明:您好,欢迎来到我的技术博客。 https://blog.csdn.net/zwyjg/article/details/8688653

 

自己修改别人的程序,

本来是一个全屏游戏,我把它改正窗口的,不过只有部分功能

全屏代码http://download.csdn.net/download/zwyjg/9914576

Hufan.java

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Vector;
public class Hufan extends JFrame implements Runnable{
	HuPanel hp;
	Manager manager;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Hufan();
	}
	public Hufan(){
		manager=new Manager();
		hp=new HuPanel();
		new Thread(this).start();
		new Thread(hp).start();
		this.add(hp);
		this.addKeyListener(hp);
		this.setTitle("Java超级玛丽");
		this.setSize(800, 700);
		this.setLocation(500, 200);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			hp.repaint();
			manager.updateCreature(hp.player, 25);
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
class HuPanel extends JPanel implements KeyListener,Runnable{
	BufferedImage bground,playerImg;
	Player player;//玛丽对象
	float offsetX;
	float offsetY;
	int mapWidth = Manager.newMap.getWidth()*64;//地图的宽度
	GameAction[] keyActions = new GameAction[600];//按键数组
    GameAction moveLeft;//左移动按键
    GameAction moveRight;//右移动按键
    GameAction jump;//跳跃
    
	public HuPanel(){
		player = new Player();
		moveLeft = new GameAction("moveLeft");
	    moveRight = new GameAction("moveRight");
	    jump = new GameAction("jump");
	    
	    keyActions[KeyEvent.VK_LEFT] = moveLeft;
	    keyActions[KeyEvent.VK_RIGHT] = moveRight;
	    keyActions[KeyEvent.VK_SPACE] = jump;
		try {
			bground=ImageIO.read(new File("background.png"));
			playerImg=ImageIO.read(new File("player1.png"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void paint(Graphics g){
		super.paint(g);
		//画界面时,都是相对坐标,
		offsetX = 400 -player.x-64;//JFrame宽度的一半减去玛丽的坐标,再减去玛丽自己的宽度。
	    offsetX = Math.min(offsetX, 0);//返回两个 double 值中较小的一个。
	    offsetX = Math.max(offsetX, 800 -mapWidth);//返回两个 double 值中较大的一个。
	    offsetY = 600 -Manager.newMap.getHeight()*64;
        //画背景
		if (bground != null) {
			float x = offsetX * (800 - 1600)/ (800 - mapWidth);
			g.drawImage(bground, (int)x, 0, null);
		}
		//画地板砖
        int firstTileX =(int)-offsetX/64;
        int lastTileX = (int)firstTileX +800/64 + 1;
       
        for (int y=0; y<Manager.newMap.getHeight(); y++) {
            for (int x=firstTileX; x <= lastTileX; x++) {
                Image image = Manager.newMap.getTile(x, y);
                if (image != null) {
                    g.drawImage(image,x*64 + (int)offsetX,y*64 + (int)offsetY,null);
                }
            }
        }
        // 画玛丽
        g.drawImage(playerImg,(int)player.x + (int)offsetX, (int)player.y + (int)offsetY,null);
       
	}
    private GameAction getKeyAction(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode < keyActions.length) {
            return keyActions[keyCode];
        }else {
            return null;
        }
    }
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		//从keyActions数组得到按键对象
        GameAction gameAction = this.getKeyAction(e);
        if (gameAction != null) {
            gameAction.press();
        }
	}
	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		GameAction gameAction = getKeyAction(e);
        if (gameAction != null) {
            gameAction.release();
        }
	}
	@Override
	public void keyTyped(KeyEvent e) {}
	@Override
	public void run() {//检测哪些键被按下
		// TODO Auto-generated method stub
		while(true){
			float velocityX = 0;
            if (moveLeft.isPressed()) {
                velocityX-=0.5f;
            }
            if (moveRight.isPressed()) {
                velocityX+=0.5f;
            }
            if (jump.isPressed()) {
                player.jump(false);
            }
            player.dx=velocityX;
            try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}


GameAction.java

/**
 * 按键类
 * @author Administrator
 *
 */
public class GameAction {
	public static final int NORMAL = 0;//正常的
	int DETECT_INITAL_PRESS_ONLY = 1;//检测初步按
    int RELEASED = 0;//释放
    int PRESSED = 1;//按下
    int WAITING_FOR_RELEASE = 2;//等待释放
    String name;
    int behavior;//行为;态度;(机器等的)运转状态;(事物的)反应
    int amount;//按键次数量
    int state;
    public GameAction(String name) {
        this.name=name;
    }
    public synchronized void press() {
        press(1);
    }
    public synchronized void press(int amount) {
        if (state != WAITING_FOR_RELEASE) {
            this.amount+=amount;
            state = PRESSED;
        }

    }
    public synchronized boolean isPressed() {
        return (getAmount() != 0);
    }
    public synchronized void release() {
        state = RELEASED;
    }
    public synchronized int getAmount() {
        int retVal = amount;
        if (retVal != 0) {
            if (state == RELEASED) {
                amount = 0;
            }
//            else if (behavior == DETECT_INITAL_PRESS_ONLY) {
//                state = WAITING_FOR_RELEASE;
//                amount = 0;
//            }
        }
        return retVal;
    }
}


Manager.java

import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.ImageIcon;
/**
 * 管理类
 * @author Administrator
 *
 */
public class Manager{
	ArrayList tiles;//地板砖图像的集合
    ArrayList lines;//地图的每行数据
    int width = 0;//地图的宽
    int height = 0;//地图的高
    BufferedReader reader;//缓存地图文本
    static float GRAVITY = 0.0015f;//重力
    Point pointCache = new Point();
    static TileMap newMap;//地图对象
	public Manager(){
		lines = new ArrayList();
		tiles = new ArrayList();
		//读取地图
		try {
			reader = new BufferedReader(new FileReader("map1.txt"));
			while(true){
				String line = reader.readLine();//读取一行
	            if (line == null) {//如果读取的一行为空
	                reader.close();
	                break;
	            }
                lines.add(line);
                //主要是为了读取最下面一行的个数,也就是地图和宽度
                width = Math.max(width, line.length());// 取两者最大的数
			}
			//读取地板砖图片到内存
	        char cha = 'A';
	        while (true) {
	            String name = "tile_" + cha + ".png";
	            File file = new File(name);
	            if (!file.exists()) {//读取的文件不存在,就退出循环
	                break;
	            }
	            tiles.add(loadImage(name));//将图片加到集合
	            cha++;
	        }
	        height = lines.size();
	        newMap = new TileMap(width, height);
	        //设置地图中。每个位置的数据
	        for (int y=0; y<height; y++) {//循环每一列
	            String line = (String)lines.get(y);
	            for (int x=0; x<line.length(); x++) {//循环每一行
	                char ch = line.charAt(x);//返回指定索引处的 char 值。
	                //检查字符是否有效
	                int tile = ch - 'A';
	                //得到的字母是否大于A,并且小于地板图片的个数 时,说明字符有效
	                if (tile >= 0 && tile < tiles.size()) {
	                    newMap.setTile(x, y, (Image)tiles.get(tile));
	                }
	            }
	        }
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
    public Image loadImage(String name) {
        String filename = name;
        return new ImageIcon(filename).getImage();
    }
    public void updateCreature(Player player,long elapsedTime)
    {
    	player.dy=player.dy+GRAVITY * elapsedTime;
        // change x 改变×
        float dx = player.dx;//x速度
        float oldX = player.x;//x坐标
        float newX = oldX + dx * elapsedTime;//
        Point tile =getTileCollision(player, newX, player.y);
        if (tile == null) {
        	player.x=newX;
        }else {
            // line up with the tile boundary线与瓦片边界
//            if (dx > 0) {
//                player.setX(tile.x/64-80);
//            }else if (dx < 0) {
//                player.setX((tile.x + 1)64);
//            }
        	player.collideHorizontal();
        }
        // change y
        float dy = player.dy;
        float oldY = player.y;
        float newY = oldY + dy * elapsedTime;
        tile = getTileCollision(player, player.x, newY);
        if (tile == null) {
        	player.y=newY;
        }else {
            // line up with the tile boundary
        	//线与瓦片边界
//            if (player.dy > 0) {
//                player.setY(tile.y/64-64);
//            }
//            else if (player.dy < 0) {
//                player.setY((tile.y + 1)/64);
//            }
        	player.collideVertical();
        }
    }
    //获取瓷砖碰撞
    public Point getTileCollision(Player sprite,float newX, float newY)
    {
        float fromX = Math.min(sprite.x, newX);
        float fromY = Math.min(sprite.y, newY);
        float toX = Math.max(sprite.x, newX);
        float toY = Math.max(sprite.y, newY);

        // get the tile locations
        //获取瓷砖的位置
        int fromTileX = (int)fromX/64;
        int fromTileY =(int)fromY/64;
        int toTileX =(int)(toX + 80 - 1)/64;
        int toTileY =(int)(toY + 64 - 1)/64;

        // check each tile for a collision
        //检查每个瓷砖的碰撞
        for (int x=fromTileX; x<=toTileX; x++) {
            for (int y=fromTileY; y<=toTileY; y++) {
                if (x < 0 || x >= newMap.getWidth() ||newMap.getTile(x, y) != null){
                    // collision found, return the tile
                	//碰撞发现,返回瓦
                    pointCache.setLocation(x, y);
                    return pointCache;
                }
            }
        }

        // no collision found
        //发现无碰撞
        return null;
    }
}


Player.java

/**
 * 玛丽类
 */
import java.awt.Point;

public class Player{
	float x;//玛丽的X坐标
	float y;
	float dx;//玛丽的X速度
	float dy;
	float JUMP_SPEED = -.95f;//跳跃速度
    boolean onGround;//在地面上
    float GRAVITY = 0.002f;//重力
	public Player(){
		
	}
	//碰撞横
    public void collideHorizontal() {
    	dx=0;
    }

    //垂直碰撞
    public void collideVertical() {
        // check if collided with ground
    	//检查如果撞到地面
        if (dy > 0) {
            onGround = true;
        }
        dy=0;//设置Y速度为0
    }
    public void jump(boolean forceJump) {
    	if (onGround || forceJump) {
            onGround = false;//false为不在地面上
            dy=JUMP_SPEED;
        }
    }
}


TileMap.java

/**
 * 地板砖地图类
 */
import java.awt.Image;
import java.util.*;

public class TileMap {
	Image[][] tiles;//图片数组
	
    public TileMap(int width, int height) {
        tiles = new Image[width][height];
    }
    public void setTile(int x, int y, Image tile) {
        tiles[x][y] = tile;
    }
    public Image getTile(int x, int y) {
    	if (x < 0 || x >= getWidth() ||y < 0 || y >= getHeight()){
            return null;
        }else {
            return tiles[x][y];
        }
    }
    public int getWidth() {
        return tiles.length;
    }

    public int getHeight() {
        return tiles[0].length;
    }
}


 map1.txt

    
    
                                     
                      IIIIIII      IIIIIII 
                                                            
                                                     EF
                 EF                                 EGD
        EF       CD                                EGAD      
BBBBBBBBGHBBBBBBBGHBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBGAAHBBBBBBBBBBB

background.png

扫描二维码关注公众号,回复: 3456154 查看本文章


player1.png


tile_A.png


tile_B.png


tile_C.png


tile_D.png


tile_E.png


tile_F.png


tile_G.png


tile_H.png


tile_I.png


猜你喜欢

转载自blog.csdn.net/zwyjg/article/details/8688653