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

java 游戏编程 (九)

阅读更多
本篇主要对java处理三维图形基本的知识做一下复习。有些地方上篇没仔细讨论。
涉及到上一篇的所有类,做一下规整,还有新的类应用描述。
1.Vector3D
这个类描述三维向量。三维向量就是(x,y,z)一个空间点,或从(0,0,0)到(x,y,z)的向量。
提供了向量加 向量减 向量乘 和向量除
还有返回了向量的长度  空间直线的长度计算公式:根号下(x+-x1)的平方+(y+-y1)+(z+-z1)的平方
区长度方法为
    
public float length() {
        return (float)Math.sqrt(x*x + y*y + z*z);
    }

旋转,比如沿x轴旋转
    public void rotateX(float cosAngle, float sinAngle) {
        float newY = y*cosAngle - z*sinAngle;
        float newZ = y*sinAngle + z*cosAngle;
        y = newY;
        z = newZ;
    }

因为沿x轴旋转,x的值忽略,重新对y,z赋值。
这里的形参是预先计算出来的值。
至于这个 float newY = y*cosAngle - z*sinAngle公式做如下解释

这个图画的很不好,
一个点旋转到另一个点
x=rcosb
y=rsinb
转过角a后,x1=rcos(a+b) y1=rsin(a+b);
得到 x1=rcosbcosa-rsinbsina  1=rsinbcosa+rsinacosb
最后
x1=xcosb-ysinb
y1=xsinb+ycosb
沿着其他轴转一样。
所以又了以上rotateX的计算方法。
2.ViewWindow
这个类具备了视图窗口的功能,并且提供投影。
再议3D的数学:
3D图形的生成就是  三维图形到镜头的连接线或向量,这些连接线经过视图窗口,在视图窗口成像。镜头离试图窗口越近,成像效果越大,这是三角问题。这个角度可以看做镜头到试图窗口的法线向量与连线的夹角。这个成像与屏幕坐标不一致,还要换算为屏幕坐标。
来看一下。
    public void project(Vector3D v) {
       //投影到视图窗口
        v.x = distanceToCamera * v.x / -v.z;
        v.y = distanceToCamera * v.y / -v.z;
       //转换为屏幕坐标
        v.x = convertFromViewXToScreenX(v.x);
        v.y = convertFromViewYToScreenY(v.y);
    }

这里形参 v 是具体的三维物体
改变其x和y的值,是通过三角函数等比例关系进行计算
distanceToCamera是视图窗口到镜头的法线长度
经过重新复制的v.x和v.y然后换算为屏幕坐标。
convertFromViewXToScreenX方法见上以篇
z是深度坐标,忽略计算。

多边形问题
多边形就是一堆顶点
3.Polygon3D
这个类将多边形表示成一堆顶点。通过Vector3D[] 存放
看看其中几个方法
   public Polygon3D(Vector3D[] vertices) {
        this.v = vertices;
        numVertices = vertices.length;
        calcNormal();
    }
   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 boolean isFacing(Vector3D u) {
        temp1.setTo(u);
        temp1.subtract(v[0]);
        return (normal.getDotProduct(temp1) >= 0);
    }


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


因为初次运行数组初始化长度不够,会引起数组越界,这个方法保证多边形的容量可以容纳多边形顶点个数

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

将多边形投影到视图窗口。

4.Transform3D
这个类主要表示旋转和平移,提供了三角函数算法。通过这个类计算旋转角度后的三角函数值,并调用Vector3D的旋转方法。
还有一个成员Vector3D location,代表了它作用于的Vector3D.

5.My3DTest1
这个类的事件监听就不再做解释了。
定义了几个成员
    private Transform3D myTransform = new Transform3D(0,0,-500);
    private Polygon3D transformedPolygon = new Polygon3D();
    private ViewWindow viewWindow;

下面会提到。
    public void update(long elapsedTime) {
        if (exit.isPressed()) {
            stop();
            return;
        }
        elapsedTime = Math.min(elapsedTime, 100);

        treeTransform.rotateAngleY(0.002f*elapsedTime);

        if (zoomIn.isPressed()) {
            treeTransform.getLocation().z += 0.5f*elapsedTime;
        }
        if (zoomOut.isPressed()) {
            treeTransform.getLocation().z -= 0.5f*elapsedTime;
        }
    }


这里是沿y轴旋转
treeTransform.rotateAngleY(0.002f*elapsedTime);
经过计算得到了cosAngleY 和 sinAngleY两个三角函数值
看关键的draw方法中的
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);
    }


        transformedPolygon.setTo(poly);
        transformedPolygon.add(myTransform);
        transformedPolygon.project(viewWindow);
这三句代码很重要。
  transformedPolygon.setTo(poly);
将多边形中的vector全都set到transformedPloygon中
transformedPolygon.add(myTransform);
这里就是进行旋转的功能,我进入方法内部说明一下。
add方法做了两件事情:
1.addRotation(myTransform);
    public void addRotation(Transform3D myTransform) {
        for (int i=0; i<numVertices; i++) {
           v[i].addRotation(myTransform);
        }
        normal.addRotation(myTransform);
    }
	public void addRotation(Transform3D myTransform) {
		// TODO Auto-generated method stub
	     rotateX(myTransform.getCosAngleX(), myTransform.getSinAngleX());
	     rotateZ(myTransform.getCosAngleZ(), myTransform.getSinAngleZ());
	     rotateY(myTransform.getCosAngleY(), myTransform.getSinAngleY());
	}

这里就是我前面说道的Vector3D里面的旋转函数方程了。经过旋转计算后,每一个顶点都会发生坐标的转移,也就实现了旋转。
2.add(myTransform.getLocation());
    public void add(Vector3D u) {
       for (int i=0; i<numVertices; i++) {
           v[i].add(u);
       }
    }


3. transformedPolygon.project(viewWindow);
投影到视图窗口
最后程序循环连线画出了三维多边形,并填充了颜色。
  • 大小: 6.7 KB
分享到:
评论
1 楼 dourokinga 2009-11-10  
楼主,这些应该是你看David Brackeen 的 Developing Games in 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