JOGL入门例子(八)---画机器人:活用长方体

我们用前面用过的知识,画一个运动的机器人.

效果如下:


 

 

主窗体类:

package com.gl3dgame.robot;               //要是想使用默认包,请去掉这行



import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;

public class RobotMain extends JFrame {
	GLRender listener=new GLRender();
	static FPSAnimator animator=null;
	public RobotMain() throws HeadlessException {
		super("画机器人:活用长方体");
		setSize(600,480);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		GLCapabilities glcaps=new GLCapabilities();
		GLCanvas canvas=new GLCanvas(glcaps);
		canvas.addGLEventListener(listener);
		//canvas.addMouseListener(listener);
		getContentPane().add(canvas, BorderLayout.CENTER);
		animator=new FPSAnimator(canvas,60,true);
                
		centerWindow(this);		
	}	
	private void centerWindow(Component frame) { // 居中窗体
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Dimension frameSize = frame.getSize();
		if (frameSize.width > screenSize.width)
			frameSize.width = screenSize.width;
		if (frameSize.height > screenSize.height)
			frameSize.height = screenSize.height;
		frame.setLocation((screenSize.width - frameSize.width) >> 1,
				(screenSize.height - frameSize.height) >> 1);

	}
	
	public static void main(String[] args) {
		final RobotMain app = new RobotMain();
		// 显示窗体
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				app.setVisible(true);
			}
		});
		// 动画线程开始
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				animator.start();
			}
		});
	}
}

 
 GL控制类:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.gl3dgame.robot;

import java.awt.Component;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

/**
 *
 * @author Administrator
 */
public class GLRender implements GLEventListener {

    private GL gl;
    private GLU glu;
    private Robot robot;
    private float rotationAngle;

    public void init(GLAutoDrawable drawable) {
        gl = drawable.getGL();
        glu = new GLU();
        robot = new Robot(gl);
        rotationAngle = 0.0f;

        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LEQUAL);
        gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);

        int w = ((Component) drawable).getWidth();
        int h = ((Component) drawable).getHeight();

        gl.glViewport(0, 0, w, h);		// 设置视点大小reset the viewport to new dimensions
        gl.glMatrixMode(GL.GL_PROJECTION);			//设置当前矩阵模式 set projection matrix current matrix
        gl.glLoadIdentity();						//把当前绘画点移动到屏幕中心 reset projection matrix

        //设置摄像机的拍摄性能 calculate aspect ratio of window
        glu.gluPerspective(52.0f, (float) w / (float) h, 1.0f, 1000.0f);

        gl.glMatrixMode(GL.GL_MODELVIEW);				//设置当前矩阵模式 set modelview matrix
        gl.glLoadIdentity();                          //把当前绘画点移动到屏幕中心 reset modelview matrix

        //播放音乐,不要就注释掉
        //new AePlayWave("wave/run.wav").start();
    }

    public void display(GLAutoDrawable drawable) {
        //刷新背景颜色 clear screen and depth buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        //把当前绘画点移动到屏幕中心 load the identity matrix (clear to default position and orientation)
        gl.glLoadIdentity();

        gl.glPushMatrix();							//保存当前矩阵 put current matrix on stack
        gl.glLoadIdentity();					//把当前绘画点移动到屏幕中心  reset matrix
        gl.glTranslatef(0.0f, 0.0f, -30.0f);	//把当前绘画点移动到(x,y,z) move to (0, 0, -30)
        gl.glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f);	//旋转(角度值,x轴,Y轴,Z轴) rotate the robot on its y-axis
        robot.DrawRobot(0.0f, 0.0f, 0.0f);		//画机器人 draw the robot
        gl.glPopMatrix();

        this.Prepare(0.2f);          //刷新机器人动作

    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
    }

    public void Prepare(float dt) {
        rotationAngle += 45.0f * dt;	// increase our rotation angle counter
        if (rotationAngle >= 360.0f) // if we've gone in a circle, reset counter
        {
            rotationAngle = 0.0f;
        }

        robot.Prepare(dt);
    }
}

 
 机器人类:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.gl3dgame.robot;

import javax.media.opengl.GL;

/**
 *
 * @author Administrator
 */
public class Robot {

    private GL gl;
    private String[] legStates = new String[2];
    private String[] armStates = new String[2];
    private float[] legAngles = new float[2];
    private float[] armAngles = new float[2];
    final int LEFT = 0;
    final int RIGHT = 1;

    public Robot(GL gl) {
        this.gl = gl;
        armAngles[LEFT] = 0.0f;
        armAngles[RIGHT] = 0.0f;
        legAngles[LEFT] = 0.0f;
        legAngles[RIGHT] = 0.0f;

        armStates[LEFT] = "FORWARD_STATE";
        armStates[RIGHT] = "BACKWARD_STATE";

        legStates[LEFT] = "FORWARD_STATE";
        legStates[RIGHT] = "BACKWARD_STATE";
    }

    private void DrawCube(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();
        gl.glTranslatef(xPos, yPos, zPos);
        gl.glBegin(GL.GL_POLYGON);
        gl.glVertex3f(0.0f, 0.0f, 0.0f);	// top face
        gl.glVertex3f(0.0f, 0.0f, -1.0f);
        gl.glVertex3f(-1.0f, 0.0f, -1.0f);
        gl.glVertex3f(-1.0f, 0.0f, 0.0f);
        gl.glVertex3f(0.0f, 0.0f, 0.0f);	// front face
        gl.glVertex3f(-1.0f, 0.0f, 0.0f);
        gl.glVertex3f(-1.0f, -1.0f, 0.0f);
        gl.glVertex3f(0.0f, -1.0f, 0.0f);
        gl.glVertex3f(0.0f, 0.0f, 0.0f);	// right face
        gl.glVertex3f(0.0f, -1.0f, 0.0f);
        gl.glVertex3f(0.0f, -1.0f, -1.0f);
        gl.glVertex3f(0.0f, 0.0f, -1.0f);
        gl.glVertex3f(-1.0f, 0.0f, 0.0f);	// left face
        gl.glVertex3f(-1.0f, 0.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 0.0f);
        gl.glVertex3f(0.0f, 0.0f, 0.0f);	// bottom face
        gl.glVertex3f(0.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 0.0f);
        gl.glVertex3f(0.0f, 0.0f, 0.0f);	// back face
        gl.glVertex3f(-1.0f, 0.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(0.0f, -1.0f, -1.0f);
        gl.glEnd();
        gl.glPopMatrix();
    }

    private void DrawArm(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();
        gl.glColor3f(1.0f, 0.0f, 0.0f);	// red
        gl.glTranslatef(xPos, yPos, zPos);
        gl.glScalef(1.0f, 4.0f, 1.0f);		// arm is a 1x4x1 cube
        DrawCube(0.0f, 0.0f, 0.0f);
        gl.glPopMatrix();
    }

    private void DrawHead(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();
        	// white
        gl.glTranslatef(xPos, yPos, zPos);
        gl.glScalef(2.0f, 2.0f, 2.0f);		// head is a 2x2x2 cube       
        gl.glColor3f(1.0f, 1.0f, 1.0f);
        DrawCube(0.0f, 0.0f, 0.0f);
        gl.glPopMatrix();
    }

    private void DrawTorso(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();
        gl.glColor3f(0.0f, 0.0f, 1.0f);	// blue
        gl.glTranslatef(xPos, yPos, zPos);
        gl.glScalef(3.0f, 5.0f, 2.0f);		// torso is a 3x5x2 cube
        DrawCube(0.0f, 0.0f, 0.0f);
        gl.glPopMatrix();
    }

    private void DrawLeg(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();
        gl.glTranslatef(xPos, yPos, zPos);

        // draw the foot
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -0.5f, 0.0f);
        DrawFoot(0.0f, -5.0f, 0.0f);
        gl.glPopMatrix();

        gl.glScalef(1.0f, 5.0f, 1.0f);		// leg is a 1x5x1 cube
        gl.glColor3f(1.0f, 1.0f, 0.0f);	// yellow
        DrawCube(0.0f, 0.0f, 0.0f);
        gl.glPopMatrix();
    }

    private void DrawFoot(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();
        gl.glColor3f(1.0f, 1.0f, 1.0f);
        gl.glTranslatef(xPos, yPos, zPos);
        gl.glScalef(1.0f, 0.5f, 3.0f);
        DrawCube(0.0f, 0.0f, 0.0f);
        gl.glPopMatrix();
    }

    public void DrawRobot(float xPos, float yPos, float zPos) {
        gl.glPushMatrix();
        gl.glTranslatef(xPos, yPos, zPos);	// draw robot at desired coordinates

        //画头 draw head and torso parts
        DrawHead(1.0f, 2.0f, 0.0f);
        DrawTorso(1.5f, 0.0f, 0.0f);

        //画左手 move the left arm away from the torso and rotate it to give "walking" effect
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -0.5f, 0.0f);
        gl.glRotatef(armAngles[LEFT], 1.0f, 0.0f, 0.0f);
        DrawArm(2.5f, 0.0f, -0.5f);
        gl.glPopMatrix();

        //画右手 move the right arm away from the torso and rotate it to give "walking" effect
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -0.5f, 0.0f);
        gl.glRotatef(armAngles[RIGHT], 1.0f, 0.0f, 0.0f);
        DrawArm(-1.5f, 0.0f, -0.5f);
        gl.glPopMatrix();

        //画左脚 move the left leg away from the torso and rotate it to give "walking" effect
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -0.5f, 0.0f);
        gl.glRotatef(legAngles[LEFT], 1.0f, 0.0f, 0.0f);
        DrawLeg(-0.5f, -5.0f, -0.5f);
        gl.glPopMatrix();

        //画右脚 move the right leg away from the torso and rotate it to give "walking" effect
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -0.5f, 0.0f);
        gl.glRotatef(legAngles[RIGHT], 1.0f, 0.0f, 0.0f);
        DrawLeg(1.5f, -5.0f, -0.5f);
        gl.glPopMatrix();

        gl.glPopMatrix();	// pop back to original coordinate system
    }

    public void Prepare(float dt) {
        //机器人动作,实际就是按规则旋转手脚
        // if leg is moving forward, increase angle, else decrease angle
        for (char side = 0; side < 2; side++) {
            // arms
            if (armStates[side] == "FORWARD_STATE") {
                armAngles[side] += 20.0f * dt;
            } else {
                armAngles[side] -= 20.0f * dt;
            }

            // change state if exceeding angles
            if (armAngles[side] >= 15.0f) {
                armStates[side] = "BACKWARD_STATE";
            } else if (armAngles[side] <= -15.0f) {
                armStates[side] = "FORWARD_STATE";
            }

            // legs
            if (legStates[side] == "FORWARD_STATE") {
                legAngles[side] += 20.0f * dt;
            } else {
                legAngles[side] -= 20.0f * dt;
            }

            // change state if exceeding angles
            if (legAngles[side] >= 15.0f) {
                legStates[side] = "BACKWARD_STATE";
            } else if (legAngles[side] <= -15.0f) {
                legStates[side] = "FORWARD_STATE";
            }
        }
    }
}

 

 实现原理就是在画所有长方前,先用gl.glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f);//旋转(角度值,x轴,Y轴,Z轴) 使矩阵里的物体旋转,,也就像地球和八大行星围绕太阳公转,,,然后各手脚自转,类似地球自转.

 

分享自己的技术论坛http://www.itneng.com/forum.php

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值