[Java 游戏编程]游戏框架预览

游戏窗体:
JFrame 容器加载一个游戏画布实现【add(GamePanel)】

pack()方法表示由JComponent来决定窗体大小

import javax.swing.JFrame;

public class Game {
	
	public static void main(String []args) {
		JFrame window = new JFrame("First Game");
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.add(new GamePanel());
		window.pack();
		window.setVisible(true);
	}
}


游戏画布:
构造函数中 

/*实现GUI event的处理*/
setFocusable(true); 设置GamePanel成为控件焦点
requestFocus();        请求获取焦点 


游戏线程的创建:
addNotify(); 方法在JFrame加载了GamePanel后执行 因为方便开始游戏线程 所以重写了该方法 该方法一定要先执行super.addNotify 父类方法 然后在执行游戏线程等


双缓冲:

private BufferedImage image; // 后备缓冲【back-buffer 是一个与屏幕大小一样的虚拟屏幕】  与屏幕 互相切换 平滑的实现游戏中动态效果
private Graphics2D g;               //  游戏画刷 用于把图像画到image中

gameRender(); //   渲染到后备缓冲 【具体细节参照实现】

gameDraw();        //   将后备缓冲绘制到屏幕上 【具体细节参照实现】


计算fps:

一般游戏为30fps
startTime = System.nanoTime(); 获取当前时间【单位纳秒】
URDTime = (System.nanoTime - startTime) / 1000000; 求出 当前循环中的游戏逻辑使用时间【单位微秒】
waitTime = targetTime - URDTimeMillis; 求出fps【单位微秒】


import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

public class GamePanel extends JPanel implements Runnable  {
	
	private static final int WIDTH = 400;
	private static final int HEIGHT = 400;
	
	private Thread thread;
	private boolean running;
	
	private BufferedImage image;	// game canvas
	private Graphics2D g; // game paint brush
	
	private int FPS = 30;
	private double averageFPS;
	
	public GamePanel() {
		setPreferredSize(new Dimension(WIDTH, HEIGHT));
		setFocusable(true);
		requestFocus();
	}
	
	// FUNCTIONS
	public void addNotify() {
		super.addNotify();
		if (thread == null) {
			thread = new Thread(this);
			thread.start();
		}
		// other game thread stuff
	}
	
	private void gameStart() {
		running = true;
	}
	
	public void run() {
		gameStart();
		
		image = new BufferedImage (WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
		g = (Graphics2D) image.getGraphics();
		
		long startTime;
		long URDTimeMillis;
		long waitTime;
		long totalTime = 0;
		
		int frameCount = 0;
		int maxFrameCount = 30;
		
		long targetTime = 1000 / FPS;
		
		// GAME LOOP
		while (running) {
			
			startTime = System.nanoTime();
			
			gameUpdate();
			gameRender();
			gameDraw();
			
			URDTimeMillis = (System.nanoTime() - startTime) / 1000000;
			waitTime = targetTime - URDTimeMillis;
			
			try {
				Thread.sleep(waitTime);
			}
			catch (Exception e) { } 
			
			totalTime += System.nanoTime() - startTime;
			frameCount++;
			if (frameCount == maxFrameCount) {
				averageFPS = 1000.0 / ((totalTime / frameCount) / 1000000);
				frameCount = 0;
				totalTime = 0;
			}
		}
	}
	
	private void gameUpdate() {
		
	}
	
	private void gameRender() {
		// draw to screen image first
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, WIDTH, HEIGHT);
		g.setColor(Color.BLACK);
		g.drawString("FPS: " + averageFPS, WIDTH / 2, HEIGHT / 2);
		
	}
	
	private void gameDraw() {
		// draw to game screen image second
		Graphics g2 = this.getGraphics();
		g2.drawImage(image, 0 , 0, null);
		g2.dispose();
	}
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值