Java实现2.5D推箱子游戏
1. 引言
通常的概念中,2D也就是所谓的二维,也就是平面图形——即由X与Y坐标构成的图形,其内容由水平的X轴向与垂直的Y轴描绘确定,也就是由长和高的形成所谓的二维平面。
而所谓3D,也称之为三维。其图形内容除了有水平的X轴向与垂直的Y轴向外还有进深的Z轴,故称三维(XYZ),也就是由长、宽、高三项要素形成所谓的三维立体。
2D与3D的主要区别在于,3D可以包含360度的信息,能从各个角度去表现,构成近似于现实空间的有质感视角;而2D通常只能表现如表格、棋盘版的平面数据。3D的立体感、光景效果要比二维平面图形要好的多,因为它的立体、光线、阴影都是相对真实存在的,而2D显然不具备这些优势。高拟真度、高自由度使得3D图形大受欢迎。
所谓的2.5D,介乎于模真的3D与完全平面的2D之间。利用斜45度的2D图片来得到3D效果,即模拟了3D的空间感,也兼具2D的灵动简单,是一种“优势”的综合体。因此2.5D在现在乃至未来的一段较长时间里还会和3D并存,直到3D图形的开发效率及表现形式能彻底取代2.5D为止。本游戏采用2.5D技术开发立体效果的推箱子游戏,效果如图1所示,玩家可以通过方向键控制人物移动箱子到目的地(蓝方块)。
图1 游戏开始后的界面
2.    2.5D游戏设计思路
在2.5D推箱子游戏中利用斜45度视角,所以假如产生如图2所示14×14的网格,则需要绘制地图中多边形,而不是矩形,其代码如下:
图2    2.5D游戏的网格界面
public void myDrawRect(Graphics g, int x ,int y){//绘制多边形
Graphics2D g2D=(Graphics2D)g;
if(g2D==null){
return;
}
GeneralPath path = new GeneralPath();
path.lineTo(x+53, y+10);
path.lineTo(x+37, y+37);
path.lineTo(x-2, y+26);
path.lineTo(x+14, y);
g2D.fill(path); //g.draw(myPath);
}
对于图2所示网格采用map1数组存储,列号向右逐次增加,行序号向左逐次增加。如图3所示。
图3 数组存储示意图
由于2.5D呈现技术与2D的绘制方式基本相同,在绘制时只需注意绘制的顺序。本游戏中地图元素采用的是等大图元(每个物件大小相同),所以可以先绘制底层地图、再绘制上层(建筑物)地图。所以采用两个数组map1,map2分别表示地图的两层,第一层数组map1中0表示白空地,l表示灰空地,2表示目的地。第二层数组map2中1表示箱子,2表示墙,3表示绿的箱子。第一层和第二层图中的-1代表该处没有任何地图元素。
//map1为第一层,map2为第二层
private int [][]map1={//第一层地图,即地板层
{-1,-1,-1,1, 0, 1, 0, 1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 2, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 2, 0, 1, 0, 1, 0, 1},
{1, 0, 2, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
mysql数据库删掉了怎么恢复{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 2, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
sql语言集{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,-1,-1,-1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,-1,-1,-1}
};
private int [][]map2={//第二层地图,建筑物
{-1,-1,-1,2, 2, 2, 2, 2,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2},
{2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0, 2},
{2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 2},
{2, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2},
{2, 0, 0, 0, 1, 2, 2, 0, 0, 0, 1, 0, 0, 2},
{2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 0, 2},
{2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2},
{2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2,-1,-1,-1},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,-1,-1,-1}
};
2.5D游戏中的图片为了配合倾斜后的X,Y坐标拼接,大部分平面图必须转换为45度图。图4是游戏中人物、箱子的45度图。这样游戏中不需要对图片再进行变换。虽然也可以在平面图上自动换算出所需的斜视图形,但细节处通常不够理想,而且耗费不必要的运算资源,还是交给美工直接切出成品图最好。
图4 人物和箱子的45度图
注意在2D游戏中箱子是平面图,2.5D游戏中的图片是45度图。图5是箱子平面图和45度图对比。
图5 箱子平面图和45度图对比
3 程序设计的步骤
3.1 创建游戏界面类(PushBox.java)
在项目中创建一个继承JPanel的PushBox类,用于显示游戏界面和实现游戏逻辑。
引入的包和相关的类:
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import GeneralPath;
import javax.swing.JPanel;
PushBox类实现KeyListener接口,从而监听键盘事件。并定义一些成员变量。public class PushBox extends JPanel implements KeyListener{
private Image pic[] = null; // 图片
int initX=200,initY=70;
//map1为第一层,map2为第二层
private int [][]map1={//第一层地图,即地板层
{-1,-1,-1,1, 0, 1, 0, 1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 3, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 3, 0, 1, 0, 1, 0, 1},
{1, 0, 3, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,-1,-1,-1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,-1,-1,-1}
kettle配置环境变量};
private int [][]map2={//第二层地图,建筑物
{-1,-1,-1,2, 2, 2, 2, 2,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2},
{2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0, 2},
{2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 2},
{2, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2},
{2, 0, 0, 0, 1, 2, 2, 0, 0, 0, 1, 0, 0, 2},
{2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 0, 2},
{2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2},
{2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2},
{2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2,-1,-1,-1},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,-1,-1,-1}
};
// 定义一些常量,对应地图的元素
final byte WALL = 2, BOX = 1, BOXONEND = 3, END = 2,
WhiteGRASS = 0, BlackGRASS = 1;
private int row = 7, column = 7;
// 加载图片
Image DefaultToolkit().getImage("images\\box.png");
Image wall = DefaultToolkit().getImage("images\\wall.png");
grep查询Image greenBox= DefaultToolkit().getImage("images\\greenbox.png");
Image man = DefaultToolkit().getImage("images\\a1.png");//人物
Image background= DefaultToolkit().getImage("images\\background.jpg");
PushBox类构造方法设定焦点在本面板,并将本面板作为监听对象。
public PushBox() {
setFocusable(true); // 设置焦点
this.addKeyListener(this);
}
myDrawRect(Graphics g, int x ,int y)绘制游戏网格中的多边形。
public void myDrawRect(Graphics g, int x ,int y){//绘制多边形
Graphics2D g2D=(Graphics2D)g;
if(g2D==null){
return;
}
GeneralPath path = new GeneralPath();
java手机游戏下载
path.lineTo(x+53, y+10);
path.lineTo(x+37, y+37);
path.lineTo(x-2, y+26);
path.lineTo(x+14, y);
g2D.fill(path); //g.draw(myPath);
}
paint(Graphics g) 画游戏界面。2.5D游戏需注意绘制的顺序。本游戏中地图元素采用的是等大图元(每个物件大小相同),所以可以先绘制底层地图、再绘制上层(建筑物)地图。
public void paint(Graphics g) {
g.clearRect(0,Width(),getHeight());
g.setColor(Color.BLACK);查看shiro版本
g.drawImage(background, 0, 0,800,800,this);//画游戏背景
//绘制第一层,即地板层
//WhiteGRASS = 0, END = 2,BlackGRASS = 1;
for(int i=0; i<map1.length; i++){
for(int j=0; j<map1[i].length; j++){
//根据索引值进行坐标转换
int X = initX+36*j-15*i;
int Y = initY+10*j+25*i;
if(map1[i][j] == WhiteGRASS){//白空地
/*设置paint的颜*/
g.setColor(new Color(255, 220, 220, 220));
}
else if(map1[i][j] == BlackGRASS){//灰空地
g.setColor(new Color(255, 170, 170, 170));

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。