`
乱世群英
  • 浏览: 18721 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

java 游戏编程 (八)

阅读更多
java3d设计的知识面比较多,常见的三维绘制有多边形造型和光束跟踪。
多边形造型(polygon modeling):将虚拟三维时间看做平面多边形。
光束跟踪(ray tracing):建立光束模型,简历眼到光源的模型。
java中常见的利用三维加速卡方法:Java3D和OpenGL关联。
Java3D核心是用OpenGL或DirectX绘制
现在我们用轻量级三维多边形绘制器,暂不用Java3D api
需要数学方面知识,但都很浅。
先考虑一个案例:我们构造一个四边形,然后它可以任意围绕x轴或y轴旋转,并且可以放大缩小。当然也可以围绕Z轴,只不过这样感觉不到3D效果。
解释一下这里的x,y,z。
在二维图形中,如果和屏幕相同的二维坐标,原点在屏幕左上方,x从左往右,y从上往下.
在三维图形中,x向右,y向上,z向里(感觉就是往屏幕里,远离人的方向)
我们从最终测试类出发,先构思出这个类应有的方法,然后回推该写的具体类和方法。
伪代码
package com.jsheng.game.test2;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;

import com.jsheng.game.util.GameAction;
import com.jsheng.game.util.GameCore;
import com.jsheng.game.util.InputManager;


/** function:
 * company: jsheng
 * @author wanghn      wanghaining9999@sina.com
 */
public class  My3DTest1 extends GameCore {

    public static void main(String[] args) {
        new My3DTest1().run();
    }

    private 多边形 a = new 多边形();
    private GameAction exit = new GameAction("exit");
    private GameAction zoomIn = new GameAction("zoomIn");
    private GameAction zoomOut = new GameAction("zoomOut");

    public void init() {
        super.init();
        InputManager inputManager = new InputManager(
            screen.getFullScreenWindow());
        inputManager.setCursor(InputManager.INVISIBLE_CURSOR);
        inputManager.mapToKey(exit, KeyEvent.VK_ESCAPE);
        inputManager.mapToKey(zoomIn, KeyEvent.VK_UP);
        inputManager.mapToKey(zoomOut, KeyEvent.VK_DOWN);
    }

    public void do设置多边形(){
    	
    }

    public void do设置多边形旋转角度(){
    	
    }

    public void update(long elapsedTime) {
        if (exit.isPressed()) {
            stop();
            return;
        }
        elapsedTime = Math.min(elapsedTime, 100);
    }

    public void draw(Graphics2D g) {
    	//处理
        this.draw多边形(g, a);
    }

    /**
        在屏幕绘制多边形
    */
    private void draw多边形(Graphics2D g,多边形 a)
    {
        
    }
}

向量,三角函数等数学知识就不介绍了,这里的程序模拟了这些算法。

说个概念:视图窗口和镜头
视图窗口是三维空间中语屏幕窗口大小相同的窗口。镜头就好像眼睛,去观察视图窗口,然后去将三维物体投影到视图窗口。(这里可以参考相关资料,或我以后整理上图更好说明这个问题)
3D中的数学
将三维物体投影到视图窗口中可以简化为直角三角形问题。
假设三维物体坐标二维点是(x,y),投影到视图窗口的二维点是(x1,y1)
从镜头到视图窗口距离是d
三维点到原点距离是z,得到:
x1=dx/-z;y1=dy/-z
d的值是我们来设置的
另外还能用夹角
从镜头出发到视图窗口两遍发射直线,两直线得到一个夹角,我们就可以通过三角函数来计算一些问题。
给出类代码,具备视图窗口和投影功能。
package com.jsheng.game.util.java3d;

import java.awt.Rectangle;
public class ViewWindow {

    private Rectangle bounds;			//视图窗口的边界
    private float angle;				//水平视角
    private float distance;  	//视图窗口到镜头的距离

    public ViewWindow(int left, int top, int width, int height,
        float angle)
    {
        bounds = new Rectangle();
        this.angle = angle;
        setBounds(left, top, width, height);
    }

    public void setBounds(int left, int top, int width,
        int height)
    {
        bounds.x = left;
        bounds.y = top;
        bounds.width = width;
        bounds.height = height;
        distance = (bounds.width/2) /
            (float)Math.tan(angle/2);
    }

    public void setAngle(float angle) {
        this.angle = angle;
        distance = (bounds.width/2) /
            (float)Math.tan(angle/2);
    }
    public float getAngle() {
        return angle;
    }

    public int getWidth() {
        return bounds.width;
    }


    public int getHeight() {
        return bounds.height;
    }

    public int getTopOffset() {
        return bounds.y;
    }

    public int getLeftOffset() {
        return bounds.x;
    }

    public float getDistance() {
        return distance;
    }



    public float convertFromViewXToScreenX(float x) {
        return x + bounds.x + bounds.width/2;
    }


    public float convertFromViewYToScreenY(float y) {
        return -y + bounds.y + bounds.height/2;
    }

    public float convertFromScreenXToViewX(float x) {
        return x - bounds.x - bounds.width/2;
    }

    public float convertFromScreenYToViewY(float y) {
        return -y + bounds.y + bounds.height/2;
    }

    //将指定的向量投影到屏幕
    public void project(Vector3D v) {
        v.x = distance * v.x / -v.z;
        v.y = distance * v.y / -v.z;

        // convert to screen coordinates
        v.x = convertFromViewXToScreenX(v.x);
        v.y = convertFromViewYToScreenY(v.y);
    }
}
]

处理多边形:
package com.jsheng.game.util.java3d;

public class Polygon3D {

    private static Vector3D temp1 = new Vector3D();
    private static Vector3D temp2 = new Vector3D();

    private Vector3D[] v;
    private int numVertices;
    private Vector3D normal;

    public Polygon3D() {
        numVertices = 0;
        v = new Vector3D[0];
        normal = new Vector3D();
    }


    public Polygon3D(Vector3D[] v) {
        this.v = v;
        numVertices = v.length;
        calcNormal();
    }

    public void setTo(Polygon3D polygon) {
        numVertices = polygon.numVertices;
        normal.setTo(polygon.normal);

        ensureCapacity(numVertices);
        for (int i=0; i<numVertices; i++) {
            v[i].setTo(polygon.v[i]);
        }
    }

    public void ensureCapacity(int length) {
        if (v.length < length) {
            Vector3D[] newV = new Vector3D[length];
            for (int i=v.length; i<newV.length; i++) {
                newV[i] = new Vector3D();
            }
            v = newV;
        
        }
    }

    public int getNumVertices() {
        return numVertices;
    }

    public Vector3D getVertex(int index) {
        return v[index];
    }

    public void project(ViewWindow view) {
        for (int i=0; i<numVertices; i++) {
            view.project(v[i]);
        }
    }

    public void add(Vector3D u) {
       for (int i=0; i<numVertices; i++) {
           v[i].add(u);
       }
    }

    public void subtract(Vector3D u) {
       for (int i=0; i<numVertices; i++) {
           v[i].subtract(u);
       }
    }

    public void add(Transform3D xform) {
        addRotation(xform);
        add(xform.getLocation());
    }

    public void subtract(Transform3D xform) {
        subtract(xform.getLocation());
        subtractRotation(xform);
    }

    public void addRotation(Transform3D xform) {
        for (int i=0; i<numVertices; i++) {
           v[i].addRotation(xform);
        }
        normal.addRotation(xform);
    }

    public void subtractRotation(Transform3D xform) {
        for (int i=0; i<numVertices; i++) {
           v[i].subtractRotation(xform);
        }
        normal.subtractRotation(xform);
    }



    public Vector3D calcNormal() {
        if (normal == null) {
            normal = new Vector3D();
        }
        temp1.setTo(v[2]);
        temp1.subtract(v[1]);
        temp2.setTo(v[0]);
        temp2.subtract(v[1]);
        normal.setToCrossProduct(temp1, temp2);
        normal.normalize();
        return normal;
    }

    public Vector3D getNormal() {
        return normal;
    }

    public void setNormal(Vector3D n) {
        if (normal == null) {
            normal = new Vector3D(n);
        }
        else {
            normal.setTo(n);
        }
    }

    public boolean isFacing(Vector3D u) {
        temp1.setTo(u);
        temp1.subtract(v[0]);
        return (normal.getDotProduct(temp1) >= 0);
    }


}

三维变换之旋转:
譬如沿z轴旋转,则z值不变。
r是旋转半径
则x = rcos(a)
y=rcos(a)
a是原始角度
x1=rcos(a+b)
y1=rsin(a+b)
b是旋转角度
x1=rcosacosb-rsinasinb
y1=rsinacosb+rsinbcosa

最后得到
x1=xcosb-ysinb
y1=xsinb+ycosb
开发包装旋转功能的类
package com.jsheng.game.util.java3d;

public class Transform3D {

    protected Vector3D location;
    private float cosAngleX;
    private float sinAngleX;
    private float cosAngleY;
    private float sinAngleY;
    private float cosAngleZ;
    private float sinAngleZ;

    public Transform3D() {
        this(0,0,0);
    }

    public Transform3D(float x, float y, float z) {
        location = new Vector3D(x, y, z);
        setAngle(0,0,0);
    }

    public Transform3D(Transform3D v) {
        location = new Vector3D();
        setTo(v);
    }


    public Object clone() {
        return new Transform3D(this);
    }


    public void setTo(Transform3D v) {
        location.setTo(v.location);
        this.cosAngleX = v.cosAngleX;
        this.sinAngleX = v.sinAngleX;
        this.cosAngleY = v.cosAngleY;
        this.sinAngleY = v.sinAngleY;
        this.cosAngleZ = v.cosAngleZ;
        this.sinAngleZ = v.sinAngleZ;
    }


    public Vector3D getLocation() {
        return location;
    }

    public float getCosAngleX() {
        return cosAngleX;
    }

    public float getSinAngleX() {
        return sinAngleX;
    }

    public float getCosAngleY() {
        return cosAngleY;
    }

    public float getSinAngleY() {
        return sinAngleY;
    }

    public float getCosAngleZ() {
        return cosAngleZ;
    }

    public float getSinAngleZ() {
        return sinAngleZ;
    }

    public float getAngleX() {
        return (float)Math.atan2(sinAngleX, cosAngleX);
    }

    public float getAngleY() {
        return (float)Math.atan2(sinAngleY, cosAngleY);
    }

    public float getAngleZ() {
        return (float)Math.atan2(sinAngleZ, cosAngleZ);
    }

    public void setAngleX(float angleX) {
        cosAngleX = (float)Math.cos(angleX);
        sinAngleX = (float)Math.sin(angleX);
    }

    public void setAngleY(float angleY) {
        cosAngleY = (float)Math.cos(angleY);
        sinAngleY = (float)Math.sin(angleY);
    }

    public void setAngleZ(float angleZ) {
        cosAngleZ = (float)Math.cos(angleZ);
        sinAngleZ = (float)Math.sin(angleZ);
    }

    public void setAngle(float angleX, float angleY, float angleZ)
    {
        setAngleX(angleX);
        setAngleY(angleY);
        setAngleZ(angleZ);
    }

    public void rotateAngleX(float angle) {
        if (angle != 0) {
            setAngleX(getAngleX() + angle);
        }
    }

    public void rotateAngleY(float angle) {
        if (angle != 0) {
            setAngleY(getAngleY() + angle);
        }
    }

    public void rotateAngleZ(float angle) {
        if (angle != 0) {
            setAngleZ(getAngleZ() + angle);
        }
    }

    public void rotateAngle(float angleX, float angleY,
        float angleZ)
    {
        rotateAngleX(angleX);
        rotateAngleY(angleY);
        rotateAngleZ(angleZ);
    }

}



最后完成最初设想的类
package com.jsheng.game.test2;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.geom.GeneralPath;

import com.jsheng.game.util.GameAction;
import com.jsheng.game.util.GameCore;
import com.jsheng.game.util.InputManager;
import com.jsheng.game.util.java3d.Polygon3D;
import com.jsheng.game.util.java3d.Transform3D;
import com.jsheng.game.util.java3d.Vector3D;
import com.jsheng.game.util.java3d.ViewWindow;

/** function:
 * company: jsheng
 * @author wanghn      wanghaining9999@sina.com
 */
public class My3DTest1 extends GameCore {

    public static void main(String[] args) {
        new My3DTest1().run();
    }
    Vector3D v1 =  new Vector3D(-50, 0, 0);
    Vector3D v2 = new Vector3D(50, 0, 0);
    Vector3D v3 = new Vector3D(-50, 100, 0);
    Vector3D v4 = new Vector3D(50, 100, 0);
    Vector3D[] vs = new Vector3D[]{v1,v2,v3,v4};
    private Polygon3D p = new Polygon3D(vs);


    private Transform3D myTransform = new Transform3D(0,0,-500);
    private Polygon3D transformedPolygon = new Polygon3D();
    private ViewWindow viewWindow;

    private GameAction exit = new GameAction("exit");
    private GameAction zoomIn = new GameAction("zoomIn");
    private GameAction zoomOut = new GameAction("zoomOut");

    public void init() {
        super.init();
        InputManager inputManager = new InputManager(
            screen.getFullScreenWindow());
        inputManager.setCursor(InputManager.INVISIBLE_CURSOR);
        inputManager.mapToKey(exit, KeyEvent.VK_ESCAPE);
        inputManager.mapToKey(zoomIn, KeyEvent.VK_UP);
        inputManager.mapToKey(zoomOut, KeyEvent.VK_DOWN);
        viewWindow = new ViewWindow(0, 0,
            screen.getWidth(), screen.getHeight(),
            (float)Math.toRadians(75));
    }

    public void update(long elapsedTime) {
        if (exit.isPressed()) {
            stop();
            return;
        }
        elapsedTime = Math.min(elapsedTime, 100);
        myTransform.rotateAngleY(0.002f*elapsedTime);
        if (zoomIn.isPressed()) {
        	myTransform.getLocation().z += 0.5f*elapsedTime;
        }
        if (zoomOut.isPressed()) {
        	myTransform.getLocation().z -= 0.5f*elapsedTime;
        }
    }

    public void draw(Graphics2D g) {
        g.setColor(Color.black);
        g.fillRect(0, 0, screen.getWidth(), screen.getHeight());
        g.setColor(Color.white);
        g.drawString("按下ESC退出",
            5, fontSize);
        trandformAndDraw(g, p);
    }


    private void trandformAndDraw(Graphics2D g,
    		Polygon3D poly)
    {
        transformedPolygon.setTo(poly);
        transformedPolygon.add(myTransform);
        transformedPolygon.project(viewWindow);
        GeneralPath path = new GeneralPath();
        Vector3D v = transformedPolygon.getVertex(0);
        path.moveTo(v.x, v.y);
        for (int i=1; i<transformedPolygon.getNumVertices(); i++) {
            v = transformedPolygon.getVertex(i);
            path.lineTo(v.x, v.y);
        }
        g.setColor(Color.red);
        g.fill(path);
    }
}
分享到:
评论
6 楼 czpsailer 2009-11-22  
支持楼主的研究精神!
5 楼 IcedCoffee 2009-11-22  
喜欢楼主这种精神!我支持你!
4 楼 dava_gosling 2009-07-03  
能否把你 这些游戏编程的代码上传,方便下载本机学习
3 楼 solonote 2009-06-25  
恩 我对我的话抱歉~
2 楼 乱世群英 2009-06-25  
solonote 写道
java不适合游戏编程,你就别折腾了

是的,java做游戏不太舒服,不如Cpp来的痛快。
研究研究而已,在很多地方还是可以触类旁通的,您说对吗?
1 楼 solonote 2009-06-24  
java不适合游戏编程,你就别折腾了

相关推荐

    JAVA游戏编程

    JAVA游戏编程 JAVA入门 JAVA游戏编程 JAVA入门 JAVA游戏编程 JAVA入门 JAVA游戏编程 JAVA入门 JAVA游戏编程 JAVA入门 JAVA游戏编程 JAVA入门

    游戏编程游戏编程java游戏编程java

    总的来说,Java游戏编程涵盖了广泛的编程知识,从基础到高级,从理论到实践,都需要深入理解和掌握。通过不断的学习和实践,开发者可以利用Java创造出丰富多样的游戏世界。在"JavaGames"这个压缩包中,可能包含了...

    Java游戏编程(游戏开发与编程序列).rar

    Java游戏编程是软件开发领域中的一个分支,它利用Java编程语言来创建各种类型的游戏,从简单的2D小游戏到复杂的3D大作。本资源“Java游戏编程(游戏开发与编程序列).rar”可能包含一系列教程、源代码示例或者相关...

    Java游戏编程原理与实践教程+随书原代码

    Java游戏编程原理与实践教程是一本深入探讨如何使用Java语言进行游戏开发的专业书籍。它涵盖了游戏编程的基础概念、核心技术以及实战技巧,旨在帮助读者从零基础到熟练掌握Java游戏开发。书中结合了大量的实例和源...

    《Java 2游戏编程》

    《Java 2游戏编程》是一本专为游戏开发爱好者和专业人士设计的教程,由美国作者Thomas Petchel撰写,并由晏利斌、孙淑敏、邵荣等人翻译成中文。这本书深入浅出地介绍了如何使用Java 2平台进行游戏开发,涵盖了从基础...

    java游戏编程导学

    Java游戏编程导学 在Java游戏开发领域,Java以其跨平台、高效稳定的特点,成为许多开发者的选择。本导学将深入探讨如何利用Java语言来创建引人入胜的游戏。Java游戏编程不仅涉及到基本的编程概念,还涵盖了图形渲染...

    Java游戏编程原理与实践教程源码

    Java游戏编程原理与实践是计算机科学中的一个重要领域,它结合了Java编程语言的特性与游戏设计的技巧。在这个教程源码包中,包含了多种经典游戏的实现,如推箱子、俄罗斯方块、超级玛丽等,这些都是游戏开发初学者和...

    java游戏编程原理与实践教程pdf+源代码

    Java游戏编程原理与实践教程是一本深入探讨如何使用Java语言进行游戏开发的专业书籍,由陈锐、夏敏捷、葛丽萍三位专家共同编著。这本书不仅涵盖了基础的编程概念,还详细介绍了游戏开发中的关键技术和实战技巧。通过...

    JAVA游戏编程.

    在JAVA游戏编程的世界里,开发者可以利用JAVA的强大功能和丰富的库来创造引人入胜的游戏体验。本课程资料集合了从基础知识到高级技术的全面学习路径,帮助你深入理解JAVA在游戏开发中的应用。 首先,从第二章的...

    Java游戏编程读书笔记

    在深入探讨Java游戏编程的世界之前,我们先要理解Java作为一种编程语言的基础特性。Java是由Sun Microsystems(现为Oracle公司)于1995年推出的,它是一种面向对象、跨平台的语言,具有“一次编写,到处运行”的特性...

    Java游戏编程入门

    想学JAVA游戏编程吗?快来了解下吧!这个资源是Java初学者的极品教程,讲的简单透彻。

    Java游戏编程

    Java游戏编程是一个涵盖广泛的主题,它涉及到使用Java编程语言来创建各种类型的游戏,从简单的2D小游戏到复杂的3D大作。在这个领域中,开发者需要掌握基础的编程概念,以及特定于游戏开发的技术。 首先,Java是一种...

    java游戏编程光盘源代码

    java游戏编程光盘源代码!~

    Java游戏编程源码教程

    Java游戏编程源码教程是一门深入浅出的学习资源,适合对Java编程有兴趣并希望进入游戏开发领域的初学者。本教程通过实例源码讲解,旨在帮助读者掌握Java在游戏开发中的应用,逐步提升编程技巧和游戏设计能力。 首先...

    Java游戏编程开发教程

    Java游戏编程开发教程是针对那些想要利用Java语言创建游戏的开发者设计的一套全面学习资源。Java作为一种跨平台、面向对象的编程语言,因其强大的性能和灵活性,在游戏开发领域有着广泛的应用。本教程将深入探讨如何...

    JAVA游戏编程源代码

    以下将详细介绍与"JAVA游戏编程源代码"相关的技术要点。 1. **Java基础知识**:Java是面向对象的语言,理解类、对象、封装、继承和多态等核心概念至关重要。同时,熟悉Java语法,如控制流(if-else,switch,循环)...

    《Java游戏编程》源代码

    在百科里搜索“Java游戏编程” (http://baike.baidu.com/view/647813.htm),就能发现一部好书——《Java游戏编程》,是深入学习java可望而不可求(难买)的好书

    Java游戏编程小手册

    "Java游戏编程小手册" 本资源是一个Java游戏编程的小手册,涵盖了Java游戏开发的基本概念、技术和框架。下面是从该资源中提炼出的知识点: 一、Java游戏开发概述 Java游戏开发是使用Java语言创建游戏的过程。...

    Java 游戏编程入门

    在《Java游戏编程入门》这本书中,作者向我们揭示了使用Java语言开发游戏的基本概念和技术。这是一本适合初学者的教程,旨在帮助那些对编程和游戏开发感兴趣的人快速掌握必要的技能。书中不仅包含了Java语言的基础...

    Java2游戏编程.pdf

    本书的出版标志着Java游戏编程技术的深入探索和应用,是对游戏开发人员和爱好者来说一本非常实用的参考书籍。 从书的内容来看,涵盖了Java游戏编程的众多方面,主要包括以下几点: 1. Java 2D游戏编程基础:书中从...

Global site tag (gtag.js) - Google Analytics