开发者社区> 科技小能手> 正文

Java中2.5D游戏(斜45度角)的设计与实现(2)

简介:
+关注继续查看
上次我已说过Java实现2.5D的关键在于斜视图坐标的转化,只要“你的美工”或者“你——的美工”技术到位,2D到2.5D的图形就简单实现来说就已 经足够了(暂不考虑日照及云雾等特殊效果)。但反过来说,2.5D界面也确实对美工有了一定的要求,如果没有好的原图,2.5D程序实现起来将事倍功半, 枉费气力不说,还达不到应有的效果。

而遗憾的是,对于我这种非游戏开发人员来说,游戏美工简直不可求更不可遇,而我搜遍google,却 也找不到多少2.5D地图可供使用(我想找皇家骑士团或最终幻想战略版那种地图,居然没有现成的……准备过两天重下游戏自己抠图……)。于是我怒从胸中 起,恶向胆边行,将一种更加极端的方法付诸于实践……

我所谓更加极端的方法,就是利用看上去向2.5D的2D程序蒙混过关——也就是所谓的“伪2.5D实现”

举例来说,下为我以前文章中曾构建过的2D地图: 



我们可以看到,在此例中角色及建筑始终由X,Y交织点确定,即采取通常的2D算法实现。

但我们都知道,3D或2D本质上区别只是视觉上的,反映到屏幕上的无外是分辨率不等的象素罢了。如果我们直接将做好的2D地图放入其中,能否起到想要的作用呢?

我们来试试看,首先,我载入一个做好的2.5D地图(取材自幻想三国,原图大小2675X930,我以800X600卷帘显示)




我们可以看到,由于采用了2.5D的视觉图,单就画面而言,通常没有人会怀疑所见到的是“斜45度立体视图”。

而问题来了,原来我们使用的传统2D地图描绘方式(见文章),要如何应用在这张伪2.5D的视图中呢?这时的难点就在于,我们要如何令原来在2D地图中使用的数组,在此图中发挥作用。

这时候有两种殊途同归的方式可供选择:一是利用ps等工具,在斜视图上生成镂空图,利用楼空图生成map数组来演算此斜视图。二是直接利用编辑器等工具在斜视图上标注通行区域,以此生成数组。

我并没有开发专用的编辑器,所以利用ps制作镂空图如下(原图于斜视图大小一致,为演示用缩小):



其中我将黑色设定为禁行区域,白色为通行区域,而生成一个二维的整形数组,代表map的所有x,y点

将字符打印成地图如下(部分)



此时,我们就可以利用地图数组在斜视图上描绘出对应的x,y点。



于通常的2D地图相同,坐标由左上x,y点开始,到右下x,y点结束,描绘出了整张地图内容(图中红色为不可移动区域,黑色为可移动区域)

那么我们现在要做的,就是将角色置身于当中了。

利用构建好的sprite类,我们能轻松的分解角色图,我将一个ro中人物置身其中。



这时,由于地图+人物俱为斜视图,所以会形成斜45度视角的错觉。

但新的问题来了,我们如何令角色移动呢?首先,我们显示角色的移动路径出来。



大 家可以看到,如果我们沿用原来2D的寻径方式,那么在移动过程中角色将按照2D路线行走。虽然对平面游戏来说在正常不过,但对于已经是"2.5D"画面的 我们来讲,显然是不能够容忍的,这时候就需要我们摒弃原先的寻径方式,将2.5D寻径的A*方法引入其中,具体方式将在下次介绍。

最后,我们去除辅助线等,运行效果如下:



由于设定的关系,此时背景画面随角色运动而卷帘移动,但就操作感受上讲,与普通的2.5D游戏是无异的。

上述操作代码如下:

package org.loon.framework.game.image;

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.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import org.loon.framework.game.script.map.BitmapToMap;
import org.loon.framework.game.sprite.Configure;
import org.loon.framework.game.sprite.Event;
import org.loon.framework.game.sprite.Sprite;
import org.loon.framework.game.sprite.SpriteGroup;

/**
 * <p>
 * Title: LoonFramework
 * </p>
 * <p>
 * Description:Java纯2D伪2.5D测试
 * </p>
 * <p>
 * Copyright: Copyright (c) 2007
 * </p>
 * <p>
 * Company: LoonFramework
 * </p>
 * 
 * 
@author chenpeng
 * @email:[email]ceponline@yahoo.com.cn[/email]
 * 
@version 0.1
 
*/

public class RpgTest extends Panel implements KeyListener, MouseListener {
    
/**
     * 
     
*/

    
private static final long serialVersionUID = 1L;

    BitmapToMap btm 
= null;

    Sprite[] roleMain 
= new Sprite[2];

    Configure config 
= null;

    
//role图行排列顺序
    final String imgList = "0,1,2,3,4,6,5,7";

    Image img 
= null;

    
public RpgTest() {
        setSize(
800600);
        setBackground(Color.BLACK);
        
        
//精灵组
        SpriteGroup sgp = new SpriteGroup();

        
//载入角色图
        Bitmap bit = new Bitmap("./imagerpg/ro.png");
        
try {
            
// 重新排列图片行列,超出索引则指定位置无图
            img = bit.getScriptRegroup(70124, imgList);
        }
 catch (Exception e) {
            e.printStackTrace();
        }

        
//创建精灵,宽70,高124
        roleMain[0= new Sprite(img, 70124);
        
//定位
        roleMain[0].setXY(45,50);
        roleMain[
0].setVisible(true);
        roleMain[
1= new Sprite(img, 70124);
        roleMain[
1].setXY(31,41);
        roleMain[
1].setVisible(true);
        
//变更角色方向
        roleMain[1].setDirection(5);
        
// 加载原始背景图,背景镂空图(行走区域标注图)
        btm = new BitmapToMap("./imagerpg/map_1.png""./imagerpg/map_1_2.png",800,600);
        
//镂空色
        btm.setFiltrateColor(new LColor(255255255));
        
//打印字符地图
        System.out.println(btm.toStringMap());
        
// 允许显示网格
        btm.setReseau(false);

        
// 加载角色
        sgp.add(roleMain[0]);
        sgp.add(roleMain[
1]);

        
// 追踪指定对象
        
// roleMain[1].setPursueObject(roleMain[0]);

        
// 以数组方式注入
        
// config=new Configure(btm,roleMain);
        
// 以spriteGroup方式注入Configure统一地图与角色管理
        config = new Configure(btm, sgp);
        
//使用2.5d视角走法
        config.set25d(true);
        
//显示移动路径
        config.setMovePath(false);
        
        setFocusable(
true);
        addKeyListener(
this);
        addMouseListener(
this);


    }


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


    
public void paint(Graphics g) {
        
// g.drawImage(img, 0, 0, this);
        config.draw(g);

        
// g.drawImage(bit.getFleshKeepOut("./s.jpg"), 0, 0, this);
        
// g.dispose();
    }


    
public void keyPressed(KeyEvent e) {
        
// 控制指定角色移动
        config.go(roleMain[0], Event.select(e.getKeyCode()));
        
// 刷新
        repaint();
    }


    
public void keyReleased(KeyEvent e) {
    }


    
public void keyTyped(KeyEvent e) {
    }



    
public void mouseClicked(MouseEvent e) {
        config.goMouse(roleMain[
0], e.getPoint(), getGraphics());
    }


    
public void mouseEntered(MouseEvent arg0) {

    }


    
public void mouseExited(MouseEvent arg0) {
    
    }


    
public void mousePressed(MouseEvent arg0) {
    }


    
public void mouseReleased(MouseEvent arg0) {

    }


    
public static void main(String[] args) {

        java.awt.EventQueue.invokeLater(
new Runnable() {
            
public void run() {
                Frame frm 
= new Frame("Java纯2D伪2.5D测试");
                frm.add(
new RpgTest());
                frm.setResizable(
false);
                frm.setSize(
800600);
                frm.addWindowListener(
new WindowAdapter() {
                    
public void windowClosing(WindowEvent e) {
                        System.exit(
0);
                    }

                }
);
                frm.setLocationRelativeTo(
null);
                frm.setVisible(
true);
            }

        }
);
    }


}


本文转自 cping 51CTO博客,原文链接:http://blog.51cto.com/cping1982/130065

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
18725 0
Java---俄罗斯方块小游戏
Java---俄罗斯方块小游戏
22 0
java游戏开发杂谈 - 游戏物体
java游戏开发杂谈 - 游戏物体现实生活中,有很多物体,每个物体的长相、行为都不同。 物体存在于不同的空间内,它只在这个空间内发生作用。 物体没用了,空间就把它剔除,不然既占地方,又需要花精力管理。
1022 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
23695 0
《Java语言程序设计》大作业报告 九宫格游戏
                《Java语言程序设计》大作业报告     中国石油大学(北京)2015 — 2016 学年第二学期     班级:_____计算机14-1_______ 姓名:_____  许 恺_________________ 学号:______2014011329___________       题意分析 程序首先需要九个可以移动的格子,大小相等,有字符串标示,其次要可以相应鼠标和键盘方向键的控制,可以自由移动,并且与此同时记录步数,最后在满足条件时弹出对话框并显示步数以及是否打破记录,关于打破记录还需要文件的操作。
1149 0
《Java 2D游戏编程入门》—— 1.2 创建Hello World应用程序
在HelloWorldApp内部,是GamePanel类,它扩展了一个JPanel。GamePanel类用于在屏幕上绘制图形。覆盖了paint方法,这使得应用程序可以访问Graphics对象。注意,之所以能使用背景颜色来清除这个面板,只是因为调用了super.paint()方法。
3077 0
23705
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载