OpenlGL游戏编程-简单的机器人制作(三)

OpenlGL游戏编程-简单的机器人制作(三)


!注意本教程是基于java的,我会在这里从创建java项目一步一步的写。(java版本为java8)


开场

上节课,我们之前学习了如何去创建一个窗口,如何让一个机器人显示在屏幕上,那么这节课,我们将学习如何让机器人自己动起来,实现走路的效果,完成一个简单的


首先,将上节课的GameRobot类打开,修改如下,我会将修改处加上注释:


package main;

import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;

public class GameRobot{

    //修改处
    float legAngle[];
    float armAngle[];
    boolean leg1 = true;
    boolean leg2 = false;

    boolean arm1 = false;
    boolean arm2 = true;
    //修改截止处
    GLAutoDrawable glad;
    GL2 gl;


    public GameRobot(GLAutoDrawable glad) {
        this.glad = glad;
        gl = glad.getGL().getGL2();
    //修改处
        legAngle = new float[2];
        armAngle = new float[2];
    //修改截止处
    }

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

        gl.glColor3f(1f, 1f, 1f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(2f, 2f, 2f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

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

        gl.glColor3f(0f, 1f, 0f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(3f, 5f, 2f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

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

        gl.glColor3f(1f, 1f, 0f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(1f, 5f, 1f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

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

        gl.glColor3f(1f, 0f, 0f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(1f, 4f, 1f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

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

        gl.glColor3f(0.5f, 0.5f, 0.5f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(0.25f, 0.25f, 0.25f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

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

        gl.glColor3f(1f, 0f, 1f);
        gl.glTranslated(xPos, yPos, zPos);
        gl.glScaled(0.75f, 0.25f, 0.25f);
        drawCube(0f, 0f, 0f);

        gl.glPopMatrix();
    }

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

        gl.glTranslated(xPos, yPos, zPos);

        gl.glBegin(GL2.GL_QUADS);

        //上面
        gl.glVertex3f(0f, 0f, -1f);
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(1f, 0f, 0f);
        gl.glVertex3f(1f, 0f, -1f);
        //下面
        gl.glVertex3f(0f, -1f, -1f);
        gl.glVertex3f(0f, -1f, 0f);
        gl.glVertex3f(1f, -1f, 0f);
        gl.glVertex3f(1f, -1f, -1f);
        //正面
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(0f, -1f, 0f);
        gl.glVertex3f(1f, -1f, 0f);
        gl.glVertex3f(1f, 0f, 0f);
        //背面
        gl.glVertex3f(0f, 0f, -1f);
        gl.glVertex3f(0f, -1f, -1f);
        gl.glVertex3f(1f, -1f, -1f);
        gl.glVertex3f(1f, 0f, -1f);
        //左面
        gl.glVertex3f(0f, 0f, -1);
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(0f, -1f, 0f);
        gl.glVertex3f(0f, -1f, -1f);
        //右面
        gl.glVertex3f(1f, 0f, -1);
        gl.glVertex3f(1f, 0f, 0f);
        gl.glVertex3f(1f, -1f, 0f);
        gl.glVertex3f(1f, -1f, -1f);

        gl.glEnd();

        gl.glPopMatrix();
    }

    public void drawRobet(float xPos, float yPos, float zPos) {
        //开始绘制机器人
        gl.glPushMatrix();

        gl.glTranslated(xPos, yPos, zPos);

        //头绘制
        drawHead(2f, 2f, 0f);
        //身躯绘制
        drawBody(1.5f, 0f, 0f);
        //绘制嘴巴
        drawMouth(2.625f,0.35f,0.25f);
        //绘制耳朵
        drawEar(1.75f,1.0f,-0.825f);
        drawEar(3.75f,1.0f,-0.825f);

    //修改处
        //右胳膊开始绘制
        gl.glPushMatrix();

        if (arm1) {
            armAngle[0] += 0.5f;
        } else {
            armAngle[0] -= 0.5f;
        }
        if (armAngle[0] >= 15.0f) {
            arm1 = false;
        }
        if (armAngle[0] <= -15.0f) {
            arm1 = true;
        }
        gl.glTranslated(0f, -0.5f, 0f);
        gl.glRotatef(armAngle[0], 1f, 0f, 0f);
        drawArm(4.5f, 0f, -0.5f);

        gl.glPopMatrix();
        //右胳膊绘制完毕

        //左胳膊开始绘制
        gl.glPushMatrix();

        if (arm2) {
            armAngle[1] += 0.5f;
        } else {
            armAngle[1] -= 0.5f;
        }
        if (armAngle[1] >= 15.0f) {
            arm2 = false;
        }
        if (armAngle[1] <= -15.0f) {
            arm2 = true;
        }
        gl.glTranslated(0f, -0.5f, 0f);
        gl.glRotatef(armAngle[1], 1f, 0f, 0f);
        drawArm(0.5f, 0f, -0.5f);

        gl.glPopMatrix();
        //左胳膊绘制完毕

        //右腿开始绘制
        gl.glPushMatrix();

        if (leg1) {
            legAngle[0] += 0.5f;
        } else {
            legAngle[0] -= 0.5f;
        }
        if (legAngle[0] >= 15.0f) {
            leg1 = false;
        }
        if (legAngle[0] <= -15.0f) {
            leg1 = true;
        }
        gl.glTranslated(0f, -0.5f, 0f);
        gl.glRotatef(legAngle[0], 1f, 0f, 0f);
        drawLeg(4.5f, -4.5f, -0.5f);

        gl.glPopMatrix();
        //右腿绘制完毕

        //左腿开始绘制
        gl.glPushMatrix();

        if (leg2) {
            legAngle[1] += 0.5f;
        } else {
            legAngle[1] -= 0.5f;
        }
        if (legAngle[1] >= 15.0f) {
            leg2 = false;
        }
        if (legAngle[1] <= -15.0f) {
            leg2 = true;
        }
        gl.glTranslated(0f, -0.5f, 0f);
        gl.glRotatef(legAngle[1], 1f, 0f, 0f);
        drawLeg(0.5f, -4.5f, -0.5f);

        gl.glPopMatrix();
        //左腿绘制完毕
    //修改截止处
        gl.glPopMatrix();
        //机器人绘制完毕
    }
}

原理就是用二个布尔类型,还判断前后摆动,用4个浮点型数来控制摆动幅度,在这里非常体现了坐标系调理清晰的重要性,这点,当你自己写的时候就深有体会了,当然你要是想象力逆天我也没有办法-_-!


还记得上节课的GameGLEventListener类么,我们要让他动起来,就需要时刻刷新页面,首先,我们要先将其修改成如下:

package main;

import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.FPSAnimator;

public class GameGLEventListener implements GLEventListener {

    GLU glu = new GLU();
    GameRobot robot;
    //修改处
    float h;
    boolean flag = true;
    float high = 45f;
    //修改截止处

    @Override
    public void init(GLAutoDrawable glad) {
        robot = new GameRobot(glad);
        GL2 gl = glad.getGL().getGL2();
        gl.glShadeModel(GL2.GL_SMOOTH);
        gl.glClearDepth(1.0f);// 设置深度缓存   
        gl.glEnable(GL2.GL_DEPTH_TEST);// 启用深度测试   
        gl.glDepthFunc(GL2.GL_LEQUAL);// 所作深度测试的类型  
        gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
    }

    @Override
    public void dispose(GLAutoDrawable glad) {

    }

    @Override
    public void display(GLAutoDrawable glad) {
        GL2 gl = glad.getGL().getGL2();
    //修改处
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(high, h, 0.1f, 100f);
        glu.gluLookAt(10f,10f, 10f, 0f, 0f, 0f, 0f, 1f, 0f);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
    //修改截止处
        //设置清除颜色为黑色,并清除颜色缓存和深度缓存
        gl.glClearColor(0f, 0f, 0f, 1f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
        //重置坐标系
        gl.glLoadIdentity();
    //修改处
        //开始绘制机器人(正面)
        gl.glPushMatrix();
        gl.glTranslated(0f, 0f, -30f);
        gl.glRotatef(0f, 0f, 1f, 0f);
        robot.drawRobet(0f, 0f, 0f);
        gl.glPopMatrix();
        //机器人绘制完毕
        //开始绘制机器人(背面)
        gl.glPushMatrix();
        gl.glTranslated(0f, 0f, -30f);
        gl.glRotatef(180f, 0f, 1f, 0f);
        robot.drawRobet(0f, 0f, 0f);
        gl.glPopMatrix();
        //机器人绘制完毕
        //开始绘制机器人(侧面)
        gl.glPushMatrix();
        gl.glTranslated(-8f, 0f, -30f);
        gl.glRotatef(90f, 0f, 1f, 0f);
        robot.drawRobet(0f, 0f, 0f);
        gl.glPopMatrix();
        //机器人绘制完毕
        //开始绘制机器人(侧面)
        gl.glPushMatrix();
        gl.glTranslated(8f, 0f, -30f);
        gl.glRotatef(270f, 0f, 1f, 0f);
        robot.drawRobet(0f, 0f, 0f);
        gl.glPopMatrix();
        //机器人绘制完毕
        gl.glFlush();
        if (flag) {
            high += 1f;
            if (high >= 180) {
                flag = false;
                high = 180;
            }
        } else {
            high -= 1f;
            if (high <= 1) {
            flag = true;
                high = 1;
            }
        }
    //修改截止处
    }

    @Override
    public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {

        GL2 gl = glad.getGL().getGL2();
        if (height <= 0) {
            height = 1;
        }
        h = (float) width / (float) height;
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
    //修改处
        glu.gluPerspective(high, h, 0.1f, 100f);
    //修改截止处
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

}
  1. 修改的地方已经表明出来了,
  2. glu.gluPerspective(high, h, 0.1f, 100f)这个函数用来投影变换的,具体的我之后会讲解
  3. glu.gluLookAt(10f,10f, 10f, 0f, 0f, 0f, 0f, 1f, 0f)这个函数用来视口变换的,具体的我之后会讲解

其他类不变


收场

执行成功后效果如下:
执行成功

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值