Java究竟怎么玩?

天地程序已定棋,人间大数待变局

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
继续前两天的博客内容,接着写Java中的ACT游戏实现,本来记得手里有C++版马里奥的角色和地图的,突然找不到丢那里了,凑活ps个GBA火影的图代替下……

运行效果如下:




此次重点演示了角色和地图的绘制……其实看过我以前写JAVA的RPG开发blog文章的早知道怎么弄的了……所以此次只帖代码……


Role.java:
package org.test.mario;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;

import org.loon.framework.game.image.Bitmap;

/**
 * <p>
 * Title: LoonFramework
 * </p>
 * <p>
 * Description:角色描述及绘制用类
 * </p>
 * <p>
 * Copyright: Copyright (c) 2008
 * </p>
 * <p>
 * Company: LoonFramework
 * </p>
 * 
 * 
@author chenpeng
 * @email:ceponline@yahoo.com.cn
 * 
@version 0.1
 
*/

public class Role {

    
private double _x;

    
private double _y;

    
private double _vx;

    
private double _vy;

    
private boolean isFlat;

    
private int _dir;

    
private int _count;

    
final static private Image role = new Bitmap("./role.gif").getImage();

    
private Map _map;

    
final static public int WIDTH = 40;

    
final static public int HEIGHT = 40;

    
final static private int SPEED = 6;

    
final static private int JUMP_SPEED = 16;

    
final static private int RIGHT = 0;

    
final static private int LEFT = 1;

    
public Role(double _x, double _y, Map _map) {
        
this._x = _x;
        
this._y = _y;
        
this._map = _map;
        _vx 
= 0;
        _vy 
= 0;
        isFlat 
= false;
        _dir 
= RIGHT;
        _count 
= 0;

        AnimationThread thread 
= new AnimationThread();
        thread.start();
    }


    
public void stop() {
        _vx 
= 0;
    }


    
public void left() {
        _vx 
= -SPEED;
        _dir 
= LEFT;
    }


    
public void right() {
        _vx 
= SPEED;
        _dir 
= RIGHT;
    }


    
public void jump() {
        
if (isFlat) {
            _vy 
= -JUMP_SPEED;
            isFlat 
= false;
        }

    }


    
public void update() {
        
//0.6为允许跳跃的高度限制,反值效果
        _vy += 0.6;

        
double newX = _x + _vx;

        Point tile 
= _map.getTileHit(this, newX, _y);
        
if (tile == null{
            _x 
= newX;
        }
 else {
            
if (_vx > 0{

                _x 
= Map.tilesToPixels(tile.x) - WIDTH;
            }
 else if (_vx < 0{
                _x 
= Map.tilesToPixels(tile.x + 1);
            }

            _vx 
= 0;
        }


        
double newY = _y + _vy;
        tile 
= _map.getTileHit(this, _x, newY);
        
if (tile == null{
            _y 
= newY;
            isFlat 
= false;
        }
 else {
            
if (_vy > 0{
                _y 
= Map.tilesToPixels(tile.y) - HEIGHT;
                _vy 
= 0;
                isFlat 
= true;
            }
 else if (_vy < 0{
                _y 
= Map.tilesToPixels(tile.y + 1);
                _vy 
= 0;
            }

        }

    }


    
public void draw(Graphics g, int offsetX, int offsetY) {
        g.drawImage(role, (
int) _x + offsetX, (int) _y + offsetY, (int) _x
                
+ offsetX + WIDTH, (int) _y + offsetY + HEIGHT, _count * WIDTH,
                _dir 
* HEIGHT, _count * WIDTH + WIDTH, _dir * HEIGHT + HEIGHT,
                
null);
    }


    
public double getX() {
        
return _x;
    }


    
public double getY() {
        
return _y;
    }


    
private class AnimationThread extends Thread {
        
public void run() {
            
while (true{
                
if (_count == 0{
                    _count 
= 1;
                }
 else if (_count == 1{
                    _count 
= 0;
                }


                
try {
                    Thread.sleep(
300);
                }
 catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }

    }


}


Map.java:
package org.test.mario;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;

import org.loon.framework.game.image.Bitmap;

/**
 * <p>
 * Title: LoonFramework
 * </p>
 * <p>
 * Description:地图绘制及描述用类
 * </p>
 * <p>
 * Copyright: Copyright (c) 2008
 * </p>
 * <p>
 * Company: LoonFramework
 * </p>
 * 
 * 
@author chenpeng
 * @email:ceponline@yahoo.com.cn
 * 
@version 0.1
 
*/

public class Map {

    
// 在以前的blog文章中我介绍过,游戏开发中通常以数组描述地图
    
// 此处1描绘为一个障碍物,0描绘为一个可通行空间
    final static public int TILE_SIZE = 32;

    
final static public int ROW = 20;

    
final static public int COL = 30;

    
final static public int WIDTH = TILE_SIZE * COL;

    
final static public int HEIGHT = TILE_SIZE * ROW;

    
final static public double GRAVITY = 0.6;

    
// 地图描述
    final static private int[][] map = {
            
2222222222222222222222,
                    
22222222 }
,
            
1000000000000000000000,
                    
00000001 }
,
            
1000000000000000000000,
                    
00000001 }
,
            
1000000000000000000000,
                    
00000001 }
,
            
1000000000000000000222,
                    
22222221 }
,
            
1111000000000000000100,
                    
00000001 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1000000000000000000120,
                    
00000001 }
,
            
1000002222222200000100,
                    
00000001 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1222220000000022222100,
                    
00000021 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1000000000000000000100,
                    
00000001 }
,
            
1000000000000000000000,
                    
00000001 }
,
            
1000000000000000000000,
                    
00000001 }
,
            
1222222222222222222222,
                    
22222221 }
 }
;

    
final static private Image tile = new Bitmap("./tile_0.gif").getImage();

    
final static private Image tile2 = new Bitmap("./tile_1.gif").getImage();

    
/**
     * 构造函数
     * 
     
*/

    
public Map() {
    }


    
public void draw(Graphics g, int offsetX, int offsetY) {
        
int firstTileX = pixelsToTiles(-offsetX);
        
int lastTileX = firstTileX + pixelsToTiles(Main._WIDTH) + 1;
        lastTileX 
= Math.min(lastTileX, COL);
        
int firstTileY = pixelsToTiles(-offsetY);
        
int lastTileY = firstTileY + pixelsToTiles(Main._HEIGHT) + 1;
        lastTileY 
= Math.min(lastTileY, ROW);

        
for (int i = firstTileY; i < lastTileY; i++{
            
for (int j = firstTileX; j < lastTileX; j++{
                
// 转换map标识
                switch (map[i][j]) {
                
case 1// 绘制砖地

                    g.drawImage(tile, tilesToPixels(j) 
+ offsetX,
                            tilesToPixels(i) 
+ offsetY, null);
                    
break;
                
case 2:
                    g.drawImage(tile2, tilesToPixels(j) 
+ offsetX,
                            tilesToPixels(i) 
+ offsetY, null);
                    
break;
                }

            }

        }

    }


    
/**
     * 换算角色与地板的撞击,并返回Point用以描述新的x,y
     * 
     * 
@param player
     * 
@param newX
     * 
@param newY
     * 
@return
     
*/

    
public Point getTileHit(Role player, double newX, double newY) {

        newX 
= Math.ceil(newX);
        newY 
= Math.ceil(newY);

        
double fromX = Math.min(player.getX(), newX);
        
double fromY = Math.min(player.getY(), newY);
        
double toX = Math.max(player.getX(), newX);
        
double toY = Math.max(player.getY(), newY);

        
int fromTileX = pixelsToTiles(fromX);
        
int fromTileY = pixelsToTiles(fromY);
        
int toTileX = pixelsToTiles(toX + Role.WIDTH - 1);
        
int toTileY = pixelsToTiles(toY + Role.HEIGHT - 1);

        
for (int x = fromTileX; x <= toTileX; x++{
            
for (int y = fromTileY; y <= toTileY; y++{

                
if (x < 0 || x >= COL) {
                    
return new Point(x, y);
                }

                
if (y < 0 || y >= ROW) {
                    
return new Point(x, y);
                }

                
if (map[y][x] == 1 || map[y][x] == 2{
                    
return new Point(x, y);
                }

            }

        }


        
return null;
    }


    
/**
     * 将Tiles转为Pixels
     * 
     * 
@param pixels
     * 
@return
     
*/

    
public static int pixelsToTiles(double pixels) {
        
return (int) Math.floor(pixels / TILE_SIZE);
    }


    
/**
     * 将Pixels转为Tiles
     * 
     * 
@param pixels
     * 
@return
     
*/

    
public static int tilesToPixels(int tiles) {
        
return tiles * TILE_SIZE;
    }

}



Main.java
package org.test.mario;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import org.loon.framework.game.image.Bitmap;

/**
 * <p>
 * Title: LoonFramework
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: Copyright (c) 2008
 * </p>
 * <p>
 * Company: LoonFramework
 * </p>
 * 
 * 
@author chenpeng
 * @email:ceponline@yahoo.com.cn
 * 
@version 0.1
 
*/

public class Main extends Panel implements Runnable, KeyListener {

    
/**
     * 
     
*/

    
private static final long serialVersionUID = 1L;

    
public static final int _WIDTH = 640;

    
public static final int _HEIGHT = 480;

    
private Map _map;

    
private Role _role;

    
private Thread _sleep;

    
private Image _screen = null;

    
private Graphics _graphics = null;

    
// 方向控制,由于是自然落体所以没有down
    private boolean LEFT;

    
private boolean RIGHT;

    
private boolean UP;

    
public Main() {
        setSize(_WIDTH, _HEIGHT);
        setFocusable(
true);
        _screen 
= new Bitmap(_WIDTH, _HEIGHT).getImage();
        _graphics 
= _screen.getGraphics();
        _map 
= new Map();
        
        _role 
= new Role(19040, _map);

        
// 监听窗体
        addKeyListener(this);

        
// 启动线程
        _sleep = new Thread(this);
        _sleep.start();
    }


    
/**
     * 运行
     
*/

    
public void run() {
        
while (true{
            
//改变方向
            if (LEFT) {
                _role.left();
            }
 else if (RIGHT) {
                _role.right();
            }
 else {
                _role.stop();
            }

            
if (UP) {
                _role.jump();
            }

            _role.update();
            repaint();
            
try {
                Thread.sleep(
20);
            }
 catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }


    
public void update(Graphics g) {
        paint(g);
    }


    
public void paint(Graphics g) {
    
        _graphics.setColor(Color.BLACK);
        _graphics.fillRect(
00, _WIDTH, _HEIGHT);

        
int offsetX = _WIDTH / 2 - (int)_role.getX();
  
        offsetX 
= Math.min(offsetX, 0);
        offsetX 
= Math.max(offsetX, _WIDTH - Map.WIDTH);

        
int offsetY =_HEIGHT / 2 - (int)_role.getY();
 
        offsetY 
= Math.min(offsetY, 0);
        offsetY 
= Math.max(offsetY, _HEIGHT - Map.HEIGHT);


        _map.draw(_graphics, offsetX, offsetY);

    
        _role.draw(_graphics, offsetX, offsetY);
        
        g.drawImage(_screen, 
0,0,null);
    }


    
public void keyPressed(KeyEvent e) {
        
int key = e.getKeyCode();
        
if (key == KeyEvent.VK_LEFT) {
            LEFT 
= true;
        }

        
if (key == KeyEvent.VK_RIGHT) {
            RIGHT 
= true;
        }

        
if (key == KeyEvent.VK_UP) {
            UP 
= true;
        }

    }


    
public void keyReleased(KeyEvent e) {
        
int key = e.getKeyCode();
        
if (key == KeyEvent.VK_LEFT) {
            LEFT 
= false;
        }

        
if (key == KeyEvent.VK_RIGHT) {
            RIGHT 
= false;
        }

        
if (key == KeyEvent.VK_UP) {
            UP 
= false;
        }

    }


    
public void keyTyped(KeyEvent e) {
    }


    
public static void main(String[] args) {
        Frame frame 
= new Frame();
        frame.setTitle(
"Java来做马里奥(2)—木叶传承");
        frame.setSize(_WIDTH, _HEIGHT
+20);
        frame.setResizable(
false);
        frame.setLocationRelativeTo(
null);
        frame.add(
new Main());
        frame.setVisible(
true);
        frame.addWindowListener(
new WindowAdapter() {
            
public void windowClosing(WindowEvent e) {
                System.exit(
0);
            }

        }
);
    }


}


 以上……

突然觉得这样做也挺有意思的,准备让木叶丸踩三代玩,啊哈哈哈……(众人曰:神经病)||||
posted on 2008-02-29 15:18  cping  阅读(265)  评论(0编辑  收藏  举报