文档章节

JAVA游戏编程学习笔记(三)Java 2D游戏底层绘图框架

J_sky
 J_sky
发布于 2015/11/06 22:34
字数 1224
阅读 271
收藏 0

前二篇记录了java如何绘制图形与动画,今天打算总结复习一下,把这些知识点集合起来,制作一个Java2D小游戏框架(暂且这么叫,好像挺牛逼似的!)。


Java AWT 下边提供一个 class 

Canvas

这是一个现成的画布,我们可以继承它来实现底层的绘制框架,为什么不直接继承JFrame?之前只是一些绘图测试,方便建立场景绘制图形,以后我们的游戏画布需要放到GUI容器里,所以继承一个类似panel的组件比较好些。


好了,底层的绘制框架实现起来很简单,代码如下:

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;

/**
 * 基于Java AWT Canvas 创建的游戏画布框架 用来绘制整个游戏的画布。
 *
 * @author J_sky
 * @version 1.0.0 2015-11-04
 */
public class MyGameCanvas extends Canvas {

    /**
     * 双缓冲的画布
     */
    Image iBuffer;
    /**
     * 双缓冲的画笔
     */
    Graphics gBuffer;

    /**
     * 构造器 初始化画板
     *
     */
    public MyGameCanvas() {
        new PaintThread().start();
    }

    /**
     * 定义一个重绘窗口的线程类,是一个内部类。 通过线程中的循环来控制动画的间隔时间。
     */
    class PaintThread extends Thread {

        @Override
        public void run() {
            while (true) {
                try {
                    repaint();//重绘画布
                    Thread.sleep(30);//间隔时间
                } catch (InterruptedException ex) {
                    System.out.println(ex);
                }
            }
        }

    }

    /**
     * 绘图方法,继承后可以重写这个方法来绘制场景及游戏元素,就可以不用。 我们制作游戏动画绘制场景主要是利用这个方法来实现。
     * 可以避免过于重写继承来的方法。也为后继加入双缓冲做准备。
     *
     * @param src
     */
    public void draw(Graphics g) {

    }

    /**
     * 重写这个方法并加入了双缓冲!
     *
     * @param g
     */
    @Override
    public void paint(Graphics g) {
        if (iBuffer == null) {
            iBuffer = createImage(this.getSize().width, this.getSize().height);
            gBuffer = iBuffer.getGraphics();
        }

        gBuffer.setColor(getBackground());
        gBuffer.fillRect(0, 0, this.getSize().width, this.getSize().height);
        draw(gBuffer);

        g.drawImage(iBuffer, 0, 0, this);
    }

    /**
     * 双缓冲重写
     *
     * @param g
     */
    @Override
    public void update(Graphics g) {

        paint(g);
    }

}


这段代码我已经实现了双缓冲,关于JAVA 双缓冲不明白的,可以百度了解一下,这里不再重复。我们只要记得draw()这方法,以后绘图都是在这里啦!


其实双缓冲JPane组件已经实现,那么我们继承JPane这个组件来实现框架试试,代码如下:

package mygameframe;

import java.awt.Graphics;
import javax.swing.JPanel;

/**
 * 基于swing.JPanel创建的游戏画布框架 用来绘制整个游戏的画布。
 *
 * @author J_sky
 * @version 1.0.0 2015-11-06 bosichong@qq.com
 */
public class MyGameJpane extends JPanel {

    /**
     * 构造器 初始化画板
     *
     */
    public MyGameJpane() {
        new PaintThread().start();//启动线程刷新。
    }

    /**
     * 定义一个重绘窗口的线程类,是一个内部类。 通过线程中的循环来控制动画的间隔时间。
     */
    class PaintThread extends Thread {

        @Override
        public void run() {
            while (true) {
                try {
                    repaint();//重绘画布
                    Thread.sleep(30);//间隔时间
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }

    }

    /**
     * 绘图方法,继承后可以重写这个方法来绘制场景及游戏元素,就可以不用。 我们制作游戏动画绘制场景主要是利用这个方法来实现。
     * 可以避免过于重写继承来的方法。也为后继加入双缓冲做准备。
     *
     * @param src
     */
    public void draw(Graphics g) {

    }

    /**
     * JPanel 双缓冲绘图的方法是paintComponent() 我们重写实现绘图。
     *
     * @param g
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.\
        draw(g);
    }

    /**
     * 重写update()也是双缓冲的必须。
     *
     * @param g
     */
    @Override
    public void update(Graphics g) {
        super.update(g); //To change body of generated methods, choose Tools | Templates.
        paintComponent(g);//双缓冲绘制
    }

}

相对之前的框架代码量要少些,我们来测试一下:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import mygameframe.MyGameJpane;

/**
 * Java2D游戏框架测试
 *
 * @author J_sky
 * @version 1.0.0 2015-11-06 bosichong@qq.com
 */
public class GameTest03 extends MyGameJpane {

    int x = 50;
    int y = 50;
    int width = 100;
    int height = 100;
    //动画变化转折点
    boolean isW = true;
    boolean isH = true;

    /**
     * 重写这个绘图的方法来绘制场景中的元素
     *
     * @param g
     */

    @Override
    public void draw(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());//绘制游戏窗口背景
        g.setColor(Color.red);
        g.fillOval(x, y, width, height);
        move();
    }

    /**
     * 圆形的移动逻辑
     */
    private void move() {
        //圆形一直下落,知道屏幕底部,就回到顶部重新下落。
        if (y < this.getHeight()) {
            y++;
        } else {
            y = 0;
        }
        //缩小方形
        if (width > 1 && isW) {
            width--;
        } else {
            isW = false;
        }

        if (height > 1 && isW) {
            height--;
        } else {
            isH = false;
        }

        //放大方形
        if (width < 100 && !isW) {
            width++;
        } else {
            isW = true;
        }

        if (height < 100 && !isW) {
            height++;
        } else {
            isH = true;
        }

    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("游戏窗口!");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(3);
        GameTest03 gc = new GameTest03();
        gc.setPreferredSize(new Dimension(400, 300));
        frame.add(gc);
        frame.pack();

    }

}

大家可以跑起来看看,至此,我们的Java2D小游戏框架搭建完毕!以后我们要做的就是考虑游戏的逻辑,用面向对象编程的思想来做游戏。我已经搞定一个小游戏,下篇笔记重点推出。

© 著作权归作者所有

J_sky

J_sky

粉丝 18
博文 25
码字总数 12709
作品 3
朝阳
程序员
私信 提问
Android 8款开源游戏引擎

1、Angle (2D Java) Angle是一款专为Android平台设计的,敏捷且适合快速开发的2D游戏引擎,基于OpenGLES技术开发。该引擎全部用Java代码编写,并且可以根据自己的需要替换里面的实现,缺陷...

鉴客
2012/03/09
231
0
Java程序员必读书单,家族又添新成员

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 有些革命出其不意地吸引了全世界的眼球。Twitter、Linux操作系统和...

异步社区
2018/05/09
0
0
Android 8款开源游戏引擎

1、Angle (2D Java) Angle是一款专为Android平台设计的,敏捷且适合快速开发的2D游戏引擎,基于OpenGLES技术开发。该引擎全部用Java代码编写,并且可以根据自己的需要替换里面的实现,缺陷...

晨曦之光
2012/03/01
1K
1
Android 8款开源游戏引擎

1、Angle (2D Java) Angle是一款专为Android平台设计的,敏捷且适合快速开发的2D游戏引擎,基于OpenGLES技术开发。该引擎全部用Java代码编写,并且可以根据自己的需要替换里面的实现,缺陷...

长平狐
2013/01/06
86
0
八款开源 Android 游戏引擎

最近无意间看到一篇关于 Android 搜索引擎的文章,于是搜索了,学不学是其次,主要是要有这方面的知识——技多不压身。下面罗列出八款常见的 Android 游戏引擎,以供参考。收费、下载量过小、...

modernizr
2014/11/13
754
1

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部