Java游戏程序设计 第3章 游戏程序的基本框架

3.1 Java2D图形绘制简介

3.1.1坐标系统
3.1.2图形处理类
  J2SE API,用于处理2D图形,功能如下
  (1)绘制和填充简单及复杂的形状
  (2)剪裁、合成图形及透明度处理
  (3)对图形进行各种几何变换
  (4)对高级字体进行处理并对字符串进行格式化
  Java2D API:Graphics类,Graphics2D类,Shape类
3.1.3 绘制几何图形
在这里插入图片描述

//建立图形绘制程序框架
import java.awt.*;
public class Test{
	public Test(){
	Frame f=new Frame("my app");//顶层容器
	MyPanel mp=new MyPanel();//绘图容器
	f.setLocation(300,200);
	f.setSize(300,300);
	f.add(mp);
	f.setVisible(true);
	}
	public static void main(String args[]){
		new Test();
	}
}

class MyPanel extends Panel{
	public void paint(Graphics g){ //重载paint方法
		
	}
}

1.使用Graphics绘图的步骤

public void paint(Graphics g){ //重载paint方法
		g.setColor(Color.blue);
		g.drawLine(20, 30, 280, 270);

在这里插入图片描述
2.使用Graphic2D对象绘图的步骤

import java.awt.geom.*;
public void paint(Graphics g){ //重载paint方法
		//建立起始点坐标,坐标为(50,50)
		Point2D p1=new Point2D.Double(50,50);
		//建立终点坐标
		Point2D p2=new Point2D.Double(100,100);
		//建立线段对象
		Line2D line=new Line2D.Double(p1,p2);
		//获取Graphics2D对象
		Graphics2D g2=(Graphics2D)g;
		g2.setColor(Color.blue);
		//调用Graphics2D绘图方法
		g2.draw(line);		
	}

在这里插入图片描述
2.使用Graphics2D对象填充图形的步骤

public void paint(Graphics g){ //重载paint方法
		//建立矩形对象
		Rectangle2D rec=new Rectangle2D.Double(20,30,250,220);
		//获取Graphics2D对象
		Graphics2D g2=(Graphics2D)g;
		//建立渐变填充对象,颜色由蓝色过度到白色
		GradientPaint blueToWhite=new GradientPaint(0,0,Color.BLUE,200,150,Color.WHITE);
		g2.setPaint(blueToWhite);
		g2.fill(rec);
	}

在这里插入图片描述
3.1.5 图形变换

	public void paint(Graphics g){ //重载paint方法
		//建立矩形对象
		Rectangle2D rec=new Rectangle2D.Double(10,10,30,30);
		//获取Graphics2D对象
		Graphics2D g2=(Graphics2D)g;
		//建立图形变换对象
		AffineTransform at=new AffineTransform();
		//设置平移变换
		at.setToTranslation(50, 50);
		//设置旋转变换
		at.rotate(Math.PI/8.0);
		//设置错切变换
		at.setToShear(2.0, 2.0);
		//设置缩放变换
		at.scale(2.0,2.0);
		//在Graphics2D对象上应用变换
		g2.setTransform(at);
		g2.setColor(Color.blue);
		g2.draw(rec);
	}

在这里插入图片描述
3.2构建游戏循环

//之前所熟知的方式是使用线程,MyPanel implements Runnable
package com.view.test;
import java.awt.*;
import java.awt.geom.*;
public class Test{
	public Test(){
	Frame f=new Frame("my app");//顶层容器
	MyPanel mp=new MyPanel();//绘图容器
	f.setLocation(300,200);
	f.setSize(300,300);
	f.add(mp);
	f.setVisible(true);
	mp.gameLoop();//调用之后终于让求移动了,书里面没有将到这个问题
	}
	public static void main(String args[]){
		new Test();
	}
}

class MyPanel extends Panel{
	private int x;
	private int y;
	private int diameter;
	public MyPanel(){
		x=50;
		y=50;
		diameter=100;
	}
	public void game(){System.out.println("hello");}//这个函数不会自动调用
	public void paint(Graphics g){ //重载paint方法,这个函数创建MyPanel对象时会自动调用
		g.setColor(Color.BLUE);
		System.out.println(x);
		g.fillOval(x,y,diameter,diameter);
	}

	public void gameLoop(){
		while(true){
			x++;
			System.out.println(x);
			for(int i=1;i<10000000;i++){}//空循环,让外循环执行速度降下来
			repaint();
		}
	}

}

3.3 双缓冲机制

3.3.1 离屏绘制
3.3.2 前屏显示

package com.view.test;
import java.awt.*;
import java.awt.geom.*;
public class Test{
	public Test(){
	Frame f=new Frame("my app");//顶层容器
	MyPanel mp=new MyPanel();//绘图容器
	f.setLocation(300,200);
	f.setSize(300,300);
	f.add(mp);
	f.setVisible(true);
	mp.gameRender();
	mp.gamePaint();
	}
	public static void main(String args[]){
		new Test();
	}
}

class MyPanel extends Panel{
	private int x;
	private int y;
	private int diameter;
	Image im=null;
	public MyPanel(){
		x=50;
		y=50;
		diameter=100;
	}
	public void game(){System.out.println("hello");}//这个函数不会自动调用
	//前屏显示
	public void gamePaint(){
		//获取当前屏幕的Graphics对象
		Graphics g=this.getGraphics();
		//将图像缓冲区中的内容复制到前屏缓冲区
		g.drawImage(im, 0,0,null);
		//释放当前屏幕的Graphics对象
	}
    //离屏绘制
	public void gameRender(){
		//建立Image对象,尺寸与程序窗口相同
		im=createImage(getWidth(),getHeight());
		//获取该图像的Graphics对象
		Graphics dbg=im.getGraphics();
		dbg.setColor(Color.BLUE);
		dbg.fillOval(x, y, diameter, diameter);
	}

}

3.4 游戏的运行框架

//前屏显示
	public void gamePaint(){
		//获取当前屏幕的Graphics对象
		Graphics g=this.getGraphics();
		//将图像缓冲区中的内容复制到前屏缓冲区
		g.drawImage(im, 0,0,null);
		//释放当前屏幕的Graphics对象
	}
    //离屏绘制
	public void gameRender(){
		//建立Image对象,尺寸与程序窗口相同
		im=createImage(getWidth(),getHeight());
		//获取该图像的Graphics对象
		Graphics dbg=im.getGraphics();
		dbg.setColor(Color.BLUE);
		dbg.fillOval(x, y, diameter, diameter);
	}

3.4 游戏的运行框架

package com.view.test;
//一个完整的游戏运行框架
import java.awt.*;
import java.awt.geom.*;
public class Test{
	public Test(){
	Frame f=new Frame("my app");//顶层容器
	MyPanel mp=new MyPanel();//绘图容器
	f.setLocation(300,200);
	f.setSize(300,300);
	f.add(mp);
	f.setVisible(true);
	mp.gameLoop();
	//调用之后终于让求移动了,书里面没有将到这个问题
	}
	public static void main(String args[]){
		new Test();
	}
}

class MyPanel extends Panel{
	private int x;
	private int y;
	private int diameter;
	Image im=null;
	public MyPanel(){
		x=50;
		y=50;
		diameter=100;
	}
	public void game(){System.out.println("hello");}//这个函数不会自动调用
	void gameLoop(){
		while(true){
			gameUpdate();
			gameRender();
			gamePaint();
		}
	}
	
	public void gameUpdate(){
		x++;
	}
	
	public void gamePaint(){
		//获取当前屏幕的Graphics对象
		Graphics g=this.getGraphics();
		//将图像缓冲区中的内容复制到前屏缓冲区
		g.drawImage(im, 0,0,null);
		//释放当前屏幕的Graphics对象
		g.dispose();
	}

	public void gameRender(){
		//建立Image对象,尺寸与程序窗口相同
		im=createImage(getWidth(),getHeight());
		//获取该图像的Graphics对象
		Graphics dbg=im.getGraphics();
		dbg.setColor(Color.BLUE);
		dbg.fillOval(x, y, diameter, diameter);
	}

}

3.5 设置帧速率

package com.view.test;
import java.awt.*;
import java.awt.geom.*;
public class Test{
	public Test(){
	Frame f=new Frame("my app");//顶层容器
	MyPanel mp=new MyPanel();//绘图容器
	Thread t=new Thread(mp);
	t.start();
	f.setLocation(300,200);
	f.setSize(300,300);
	f.add(mp);
	f.setVisible(true);
	//调用之后终于让求移动了,书里面没有将到这个问题
	}
	public static void main(String args[]){
		new Test();
	}
}

class MyPanel extends Panel implements Runnable{
	private int x;
	private int y;
	private int diameter;
	Image im=null;
	public MyPanel(){
		x=50;
		y=50;
		diameter=100;
	}
	public void game(){System.out.println("hello");}//这个函数不会自动调用

	public void gameUpdate(){
		x++;
	}
	
	public void gamePaint(){
		//获取当前屏幕的Graphics对象
		Graphics g=this.getGraphics();
		//将图像缓冲区中的内容复制到前屏缓冲区
		g.drawImage(im, 0,0,null);
		//释放当前屏幕的Graphics对象
		g.dispose();
	}

	public void gameRender(){
		//建立Image对象,尺寸与程序窗口相同
		im=createImage(getWidth(),getHeight());
		//获取该图像的Graphics对象
		Graphics dbg=im.getGraphics();
		dbg.setColor(Color.BLUE);
		dbg.fillOval(x, y, diameter, diameter);
	}
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		//整型常量FPS保存帧速率值
		final int FPS=50;
		long t1,t2,dt,sleepTime;
		//计算每一次循环需要的时间,单位毫秒
		long period=1000/FPS;
		//保存游戏循环执行前的系统时间,单位毫秒
		t1=System.nanoTime();
		
		while(true){
			gameUpdate();
			gameRender();
			gamePaint();
			t2=System.nanoTime();//游戏循环执行后的系统时间,单位纳秒
			dt=(t2-t1)/1000000L;//本次循环实际花费时间,单位转换为毫秒
			sleepTime=period-dt;//本次循环剩余的时间,单位毫秒
			if(sleepTime<=0)//防止sleepTime为负数
				sleepTime=2;
			try {
				Thread.sleep(sleepTime);//线程休眠
			} catch (InterruptedException ex) {
				ex.printStackTrace();
				// TODO: handle exception
			}
			t1=System.nanoTime();//重新获取当前系统时间
		}
	}

}

在这里插入图片描述

//使用计数器对象来设置帧速率
public class GamePanel extends Panel{
	... ...
	public void gameStart(){//用该方法来启动计时器
		Timer t=new Timer();//建立计时器对象
		MyTimerTask game=new MyTimerTask();//建立计时任务对象
		t.scheduleAtFixedRate(game,0,1000/50);//设定帧速率并启动计时任务
	}
}
class myTimerTask extends TimerTask{//建立内部类,继承TimerTask类
	public void run{
		while(true){
			gameUpdate();
			gameRender();
			gamePaint();
		}
	}
}

3.6 Applet 游戏程序框架

import java.applet.*;
public class gameApplet extends Applet{
	GamelPanel gp;
	public void init(){
	gp=new GamePanel();
	add(gp);
	setVisible(true);
	}
	public void start(){
		gp.gamestart();
	}

}
<html>
<applet code="gameApplet.class" width=500 height=500>
</applet>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值