算法冒泡排序
没啥好说的,就是优化的时候加了一遍boolean值,判断这次循环有进行数据交换吗,没有就认为已经完结了,跳出大循环
package com.itbaizhan;
import java.util.Arrays;
public class TestBubbleSort {
public static void main(String[] args) {
int[] values = {3,4,1,5,9,4,2,4,5,0};
//int[] values = {2,1,3,4,5,6,7};
System.out.println(Arrays.toString(values));
for (int i =0;i<values.length;i++){
boolean flag = true;
for (int j = 0;j<values.length-1-i;j++){
if(values[j]>values[j+1]){
int t = values[j];
values[j]=values[j+1];
values[j+1]=t;
flag=false;
}
}
//如果本次循环没有交换,那么结束排序
if(flag){
break;
}
System.out.println("第"+i+"次循环:"+Arrays.toString(values));
}
}
}
二分法查找
package com.itbaizhan;
public class TestBinarySearch {
public static void main(String[] args) {
int[] values = {1,2,3,4,5,6,7};
int value=9;
int index=binarySearch(values,value);
if(index!=-1)
System.out.println("查找数组values中是否有"+value+",下标索引为:"+index);
else
System.out.println("查找数组values中是否有"+value+",未找到该数");
}
public static int binarySearch(int[] array,int value){
int low = 0;
int high = array.length-1;
while(low<=high){
int middle=(low+high)/2;
if(value==array[middle]){
return middle;
}
if(value>array[middle]){
low=middle+1;
}
if(value<array[middle]){
high=middle-1;
}
}
return -1;
}
}
实战项目:飞机大战
基础类:GameObject(游戏对象类)、GameUitl(游戏工具类)、MyGameFrame(游戏界面)
游戏对象类:Plane(飞机类)、Shell(子弹类)、Explode(爆炸特效类,这个类没有继承GameObject)
GameObject类
package com.bjsxt;
import java.awt.*;
//游戏物体的根类
public class GameObject {
Image img; //对应的图片
int x,y; //坐标
int speed; //物体移动速度
int width,height;//物体的宽度和高度
//画自己
public void drawMySelf(Graphics g){
g.drawImage(img,x,y,width,height,null);
}
//返回该物体对应的矩形
public Rectangle getRec(){
return new Rectangle(x,y,width,height);
}
public GameObject(){}
public GameObject(Image img, int x, int y, int speed, int width, int height) {
this.img = img;
this.x = x;
this.y = y;
this.speed = speed;
this.width = width;
this.height = height;
}
public GameObject(Image img, int x, int y, int speed) {
this(img,x,y);
this.x = x;
this.y = y;
this.speed = speed;
}
public GameObject(Image img, int x, int y) {
this(img);
this.x = x;
this.y = y;
}
public GameObject(Image img) {
this.img = img;
if(this.img!=null){
this.width=img.getWidth(null);
this.height=img.getHeight(null);
}
}
}
GameUitl类
package com.bjsxt;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
//工具类
public class GameUitl {
public static final int FRAME_WIDTH=500;
public static final int FRAME_HIGHT=500;
public static Image getTmage(String path){
Image img=null;
URL url = GameUitl.class.getClassLoader().getResource(path);
try{
img= ImageIO.read(url);
}catch (IOException e){
e.printStackTrace();
}
return img;
}
}
MyGameFrame类
package com.bjsxt;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;
import static com.bjsxt.GameUitl.*;
public class MyGameFrame extends Frame {
Image bgImg= GameUitl.getTmage("images/break.jpeg");
Image planeImg= GameUitl.getTmage("images/飞机.png");
//加载实体,飞机、子弹,爆炸
Plane plane = new Plane(planeImg,200,200,7,40,40);
Shell[] shells= new Shell[50];
Explode explode; //声明炮弹M
//记录时间的
Date starTime = new Date();
Date endTime;
int period;
public static void main(String[] args) {
MyGameFrame frame=new MyGameFrame();
frame.launchFrame();
}
//初始化窗口
public void launchFrame(){
this.setTitle("飞机大战");
this.setVisible(true);
this.setSize(FRAME_WIDTH,FRAME_HIGHT);
this.setLocation(300,300);
//窗口监听 增加关闭窗口的动作
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//启动窗口绘制线程
new PaintThread().start();
//启动键盘监听
this.addKeyListener(new KeyMoniteor());
//初始化所有炮弹
for(int i=0;i<shells.length;i++){
shells[i]=new Shell();
}
}
//绘制窗口,绘制背景和飞机
@Override
public void paint(Graphics g) {
// System.out.println("窗口绘制...");
g.drawImage(bgImg,0,0,FRAME_WIDTH,FRAME_HIGHT,null);
plane.drawMySelf(g);
//子弹循环
for(Shell shell:shells){
//画子弹
shell.drawMySelf(g);
//碰撞监测,子弹和飞机是否碰撞
boolean peng = shell.getRec().intersects(plane.getRec());
if(peng && plane.live){
//飞机时候,生命开关关掉,记录死亡时间
//System.out.println("飞机死了");
plane.live = false;
shell.live = false;
endTime=new Date();
period=(int)((endTime.getTime()-starTime.getTime())/1000);
}
}
//死亡画面,播放坠毁特效
if(!plane.live){
printInfo(g,"飞机死了!",20,plane.x,plane.y,Color.white);
printInfo(g,"您坚持了"+period+"秒",40, FRAME_WIDTH/4,FRAME_HIGHT/2,Color.white);
if(explode==null){
explode=new Explode(plane.x,plane.y,plane.width,plane.height);
}
explode.draw(g);
}
// g.drawLine(100,50,400,400);
// g.drawRect(100,50,400,400);
// g.drawOval(100,50,400,400);
}
//在界面上显示字体
public void printInfo(Graphics g,String str,int size, int x, int y,Color color){
Font oldFont = g.getFont();
Color oldColor = g.getColor();
Font f= new Font("宋体",Font.BOLD,size);
g.setFont(f);
g.setColor(color);
g.drawString(str,x,y);
g.setFont(oldFont);
g.setColor(oldColor);
}
//键盘监听内部类
class KeyMoniteor extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
plane.addDirection(e);
}
@Override
public void keyReleased(KeyEvent e) {
plane.minusDirection(e);
}
}
//重画线程
class PaintThread extends Thread{
@Override
public void run() {
while(true){
repaint(); //内部会自动调用paint方法
try{
Thread.sleep(40); //1s=1000ms
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
//解决闪烁问题AWT技术有这个问题,他是最早的技术
private Image offScreenImage = null;
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage = this.createImage(FRAME_WIDTH,FRAME_HIGHT);
}
Graphics gOff = offScreenImage.getGraphics();
paint(gOff);
g.drawImage(offScreenImage,0,0,null);
}
}
Plane类
package com.bjsxt;
import java.awt.*;
import java.awt.event.KeyEvent;
//飞机类
public class Plane extends GameObject{
boolean left,up,right,down;
boolean live=true;
public Plane(Image img, int x, int y, int speed) {
super(img, x, y, speed);
}
public Plane(Image img, int x, int y, int speed, int width, int height) {
super(img, x, y, speed, width, height);
}
//对象自带方法:画飞机判断,如果判断方向在,就对x,y进行移动
@Override
public void drawMySelf(Graphics g) {
if(!live){
return;
}
super.drawMySelf(g);
if(left){
x-=speed;
}
if(right){
x+=speed;
}
if(up){
y-=speed;
}
if(down){
y+=speed;
}
}
//两个对象自带方法:通过输入的键盘数值判断bool是否有这个方向的朝向
public void addDirection(KeyEvent e) {
switch (e.getKeyCode()){
case KeyEvent.VK_LEFT:
left=true;
break;
case KeyEvent.VK_RIGHT:
right=true;
break;
case KeyEvent.VK_UP:
up=true;
break;
case KeyEvent.VK_DOWN:
down=true;
break;
}
}
public void minusDirection(KeyEvent e) {
switch (e.getKeyCode()){
case KeyEvent.VK_LEFT:
left=false;
break;
case KeyEvent.VK_RIGHT:
right=false;
break;
case KeyEvent.VK_UP:
up=false;
break;
case KeyEvent.VK_DOWN:
down=false;
break;
}
}
}
Shell类
package com.bjsxt;
import java.awt.*;
public class Shell extends GameObject{
double degree;
boolean chuJie = false;
boolean live = true;
public Shell(){
degree = Math.random()*Math.PI*2;
x=20;
y=20;
width=10;
height=10;
speed=4;
}
@Override
public void drawMySelf(Graphics g) {
if(!live){
return;
}
Color c = g.getColor();
g.setColor(Color.yellow);
g.drawOval(x,y,width,height);
//炮弹沿任意角度飞行
x += speed*Math.cos(degree);
y += speed*Math.sin(degree);
//边界碰撞回弹
if(y>GameUitl.FRAME_HIGHT || y<30 && chuJie == false){
degree = -degree+Math.random();
chuJie=true;
}
if(x<GameUitl.FRAME_WIDTH && x>0 && y<GameUitl.FRAME_HIGHT && y>30){
chuJie=false;
//System.out.println("x="+x+",y="+y);
//System.out.println("在界内");
}
if(x>GameUitl.FRAME_WIDTH || x<0 && chuJie == false){
degree = Math.PI-degree+Math.random();
chuJie=true;
}
g.setColor(c);
}
}
Explode类
package com.bjsxt;
import java.awt.*;
public class Explode {
double x,y;
static Image[] imags=new Image[21];
int width,height;
//静态加载图片
static {
for (int i = 0; i < imags.length; i++) {
imags[i]=GameUitl.getTmage("images/boob/爆炸"+(i+1)+".png");
//java可能懒加载,就是不加载图片,调个方法让他加载
imags[i].getWidth(null);
}
}
public Explode(double x, double y) {
this.x = x;
this.y = y;
}
public Explode(double x, double y, int width, int height) {
this(x,y);
this.width = width;
this.height = height;
}
//依次渲染图
int count;
boolean live=true;
public void draw(Graphics g){
if(!live){
return;
}
if(count<imags.length){
g.drawImage(imags[count],(int)x,(int)y,width,height,null);
count++;
}else {
live=false;
}
}
}
所有代码都在同一包下,游戏开始,50颗子弹随机移动,飞机躲避子弹,直到被撞到,游戏结束
- 子弹和飞机都继承于游戏对象类,游戏对象类有非常基础的信息(位置x,y,采用那张图片,在窗口上绘画自己的方法,返回自身矩形的方法-碰撞监测需要用)
- 游戏工具类中有如何导入图片存储到Image对象的方法,以及窗口的长宽常量
- MyGameFrame类非常复杂,大部分运行机制都在这个类中,里面有加载的背景、飞机图片、 飞机对象、50发子弹对象、炮弹爆炸特效类、记录时间
- 初始化窗口:窗口标题、显示窗口、设置窗口大小、出现在屏幕的位置,窗口监听-增加开关闭窗口的动作,窗口绘制线程(一秒执行大概25次这个paint方法),批量初始化所有子弹
- paint方法:绘制背景、飞机对象自我绘制、遍历子弹数组{子弹自我绘制,碰撞监测,看是否碰到飞机了,碰到了游戏结束,飞机生命false,记录结束时间,计算坚持了多长时间}、如果飞机生命false了{写两句话:一句飞机死了,一句坚持了几秒,播放爆炸特效}
- printInfo方法:在指定位置写一句话
- 键盘监听内部类:里面两个方法,判断按下、判断抬起
- 按下方法执行飞机对象中按下方向方法
- 抬起方法执行飞机对象中抬起方向方法
- 重画线程(也是一个内部类):只做了一件事:就是每秒多次执行paint方法
- update方法:解决了早期AWT技术画面闪烁问题
- 飞机类只有简单三个方法,俩构造方法--初始化飞机的用那张图片,位置,速度,大小
- 画飞机,每次位置随着四个方向bool值改变,实现移动
- 剩余两个方法则是 通过输入键盘值(上下左右)判断四个方向bool值的正负,从而决定打开或者关闭四个方向的bool值
- 子弹类定义了一个随机方向degree和判断是否出界
- 初始化随机给一个方向,其他的出生点位置、大小、速度都是定死的
- 绘画黄色圆圈,xy轴按给定随机方向移动,判断是否碰到边界,碰到回弹
- 爆炸类,只声明,只有飞机死亡的时候才new出来,出来就绘制爆炸,一共21张图片,依次渲染,形成爆炸画面