java 游戏编程 (三)

上篇说到的动画,在显示上有个比较大的问题,动画在闪烁。这是因为程序不断直接绘制屏幕造成。避免闪烁,我们用双倍缓存。缓存区是绘图时使用的屏外内存。双缓存不是直接绘制屏幕,而是绘制到后缓存区然后复制到屏幕。

page flipping技术。跳过复制缓存区,直接把后缓存区变为显示缓存区。

以上这些情况用BufferStrategy类处理。Jframe,Window这些对象都有BufferStrategy。调用getBufferStrategy()方法。调用show方法显示绘图缓存区,当然之前要用createBufferStrategy()方法创建
如:

frame.createBufferStrategy(2); //表示两个缓冲区
BufferStrategy str = frame.getBufferStrategy();
Graphics g = str.getDrawGraphics()
g.dispose();
str.show();


这样我们对MyScreenMgr 这个类进行扩充。MyScreenMgr 这个类在[url]http://luanshiqunying-sina-com.iteye.com/blog/408389[/url]第一篇里
/**
*
*/
package com.jsheng.game.util;

import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JFrame;

/** function:
* company: jsheng
* @author wanghn wanghaining9999@sina.com
* describe:
*/
public class MyScreenMgr {

private GraphicsDevice device;

public MyScreenMgr() {
GraphicsEnvironment environment =
GraphicsEnvironment.getLocalGraphicsEnvironment();
device = environment.getDefaultScreenDevice();
}
public DisplayMode findFirstCompatibleMode(
DisplayMode modes[])
{
DisplayMode goodModes[] = device.getDisplayModes();
for (int i = 0; i < modes.length; i++) {
for (int j = 0; j < goodModes.length; j++) {
if (displayModesMatch(modes[i], goodModes[j])) {
return modes[i];
}
}

}

return null;
}

public DisplayMode getCurrentDisplayMode() {
return device.getDisplayMode();
}
public boolean displayModesMatch(DisplayMode mode1,
DisplayMode mode2)

{
if (mode1.getWidth() != mode2.getWidth() ||
mode1.getHeight() != mode2.getHeight())
{
return false;
}

if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&
mode1.getBitDepth() != mode2.getBitDepth())
{
return false;
}

if (mode1.getRefreshRate() !=
DisplayMode.REFRESH_RATE_UNKNOWN &&
mode2.getRefreshRate() !=
DisplayMode.REFRESH_RATE_UNKNOWN &&
mode1.getRefreshRate() != mode2.getRefreshRate())
{
return false;
}

return true;
}
public void setFullScreen(DisplayMode displayMode){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setIgnoreRepaint(true);
frame.setResizable(false);

device.setFullScreenWindow(frame);

if (displayMode != null &&
device.isDisplayChangeSupported())
{
try {
device.setDisplayMode(displayMode);
}
catch (IllegalArgumentException ex) { }
frame.setSize(displayMode.getWidth(),
displayMode.getHeight());
}
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
frame.createBufferStrategy(2);
}
});
}
catch (InterruptedException ex) {
// 处理
}
catch (InvocationTargetException ex) {
// 处理
}
}

/*
* 取得显示图形描述表,使用双缓存,需要调用update方法
*/
public Graphics2D getGraphics() {
Window window = device.getFullScreenWindow();
if (window != null) {
BufferStrategy strategy = window.getBufferStrategy();
return (Graphics2D)strategy.getDrawGraphics();
}
else {
return null;
}
}

public void update() {
Window window = device.getFullScreenWindow();
if (window != null) {
BufferStrategy strategy = window.getBufferStrategy();
if (!strategy.contentsLost()) {
strategy.show();
}
}
}
public int getWidth() {
Window window = device.getFullScreenWindow();
if (window != null) {
return window.getWidth();
}
else {
return 0;
}
}

public int getHeight() {
Window window = device.getFullScreenWindow();
if (window != null) {
return window.getHeight();
}
else {
return 0;
}
}

public Window getFullScreenWindow() {
return device.getFullScreenWindow();
}

/*
* 生成与当前显示器兼容的图像,就是与显示器有相同位深度和颜色模型的图像。
* 生成的图像为BufferedImage,是系统内存中存放的非加速图像。
*/
public BufferedImage createCompatibleImage(int w, int h,
int transparancy)
{
Window window = device.getFullScreenWindow();
if (window != null) {
GraphicsConfiguration gc =
window.getGraphicsConfiguration();
return gc.createCompatibleImage(w, h, transparancy);
}
return null;
}

public void reScreen() {
Window window = device.getFullScreenWindow();
if (window != null) {
window.dispose();
}
device.setFullScreenWindow(null);
}
}

对这个新类的使用注意一点就是显示的选择方式改为提供一系列的可选的显示方式,由这个类自己去寻找合适的显示方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值