闲来无事写了个飞机小游戏。
设定很简单,子弹打到飞机就结束游戏。
实现步骤如下,有问题可以评论区讨论:
首先建立一个PlayGame项目和它之下的包:
MyGameFrame(游戏实现)类:
package game;
import javax.swing.*;
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;
public class MyGameFrame extends Frame {
Image plane = GameUtil.getImage("images/plane.jpg");
Image bgi = GameUtil.getImage("images/bgi.jpg");
//窗口绘制方法,g变量相当于画笔
Plane p = new Plane(plane,220,450);
BallBall bb = new BallBall();
BallBall[] balls = new BallBall[20];
Explode bao;
// Boom boo =new Boom();
Date startTime = new Date();
Date endTime;
int period;//游戏持续的时间
@Override
public void paint(Graphics g) {
g.drawImage(bgi,0,0,null);
p.drawSelf(g);
// bb.draw(g);
for (int i = 0; i < balls.length; i++) {
balls[i].draw(g);
boolean peng = balls[i].getRect().intersects(p.getRect());
if(peng){
p.live = false;
if(bao == null){
bao = new Explode(p.x,p.y);
endTime = new Date();
period = (int) ((endTime.getTime() - startTime.getTime()) / 1000);
}
bao.drawBoom(g);
//游戏结束提示方案一:
int result = JOptionPane.showConfirmDialog(this, "共存活"+period+"秒,你真棒!", "提示", JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
if(result == JOptionPane.OK_OPTION){
System.exit(0);
}
}
/*游戏结束提示方案二:
g.setColor(Color.GRAY);
g.setFont(Font.getFont("微软雅黑"));
g.drawString("共存活"+period+"秒",220,40);
*/
}
}
//帮助我们反复重画窗口
class PaintThread extends Thread{
@Override
public void run() {
while(true){
// System.out.println("窗口重画!");
repaint();
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//实现键盘监听
class KeyMonitor extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
p.addDirection(e);
}
@Override
public void keyReleased(KeyEvent e) {
p.minusDirection(e);
}
}
//初始化窗口
public void launchFrame(){
this.setTitle("魏万万!");
this.setVisible(true);
this.setSize(500,500);
this.setLocation(300, 100);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
new PaintThread().start();//启动重画窗口的线程
addKeyListener(new KeyMonitor());//给窗口增加键盘的监听
//初始化20个炮弹
for (int i = 0; i < balls.length; i++) {
balls[i] = new BallBall();
}
}
public static void main(String[] args) {
MyGameFrame mgf = new MyGameFrame();
mgf.launchFrame();
}
//双缓冲解决闪烁问题
private Image offScreenImage = null;
public void update(Graphics g){
if(offScreenImage == null)
offScreenImage = this.createImage(500,500);
Graphics gOff = offScreenImage.getGraphics();
paint(gOff);
g.drawImage(offScreenImage,0,0,null);
}
}
GameUtil(游戏工具)类:
package game;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
public class GameUtil {
//工具类最好把构造器私有化
private GameUtil(){
}
public static Image getImage(String path){
BufferedImage bi =null;
try {
URL u = GameUtil.class.getClassLoader().getResource(path);
bi = ImageIO.read(u);
} catch (IOException e) {
e.printStackTrace();
}
return bi;
}
}
GameObject(游戏中所涉及元素的父)类:
package game;
import java.awt.*;
public class GameObject {
Image img;
double x,y;
int speed;
int width,height;
public void drawSelf(Graphics g){
g.drawImage(img,(int)x,(int)y,null);
}
public GameObject() {
}
public GameObject(Image img, double x, double y, int speed, int width, int height) {
//super();
this.img = img;
this.x = x;
this.y = y;
this.speed = speed;
this.width = width;
this.height = height;
}
public GameObject(Image img, double x, double y) {
//super();
this.img = img;
this.x = x;
this.y = y;
}
//返回物体所在的矩形,便与后续的碰撞检测
public Rectangle getRect(){
return new Rectangle((int)x,(int)y,width,height);
}
}
BallBall(子弹)类:
package game;
import java.awt.*;
public class BallBall extends GameObject{
double degree;
public BallBall(){
x = 200;
y = 200;
width = 10;
height = 10;
speed = 3;
degree = Math.random()*Math.PI*2;//定义degree范围为0-2π
}
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.YELLOW);
g.fillOval((int)x,(int)y,width,height);
// System.out.println("我被画出来了");
x += speed*Math.cos(degree);
y += speed*Math.sin(degree);
if(x<0 || x>485){
degree = Math.PI-degree;
}
if(y<30 || y>485){
degree = -degree;
}
g.setColor(c);
}
}
Plane(飞机)类:
package game;
import java.awt.*;
import java.awt.event.KeyEvent;
public class Plane extends GameObject{
int speed = 3;
boolean left,right,up,down;
boolean live = true;
public void drawSelf(Graphics g){
if (live) {
g.drawImage(img,(int)x,(int)y,null);
if(left){
x -= speed;
}
if(right){
x += speed;
}
if(up){
y -= speed;
}
if(down){
y += speed;
}
}
}
public Plane(Image img,double x,double y){
this.img = img;
this.x=x;
this.y=y;
this.width = img.getWidth(null);
this.height = img.getHeight(null);
}
public void addDirection(KeyEvent e){
switch(e.getKeyCode()){
//keyEvent.VK_可以找到键的打印值
case KeyEvent.VK_LEFT:
left = true;
break;
case 38:
up = true;
break;
case 39:
right = true;
break;
case 40:
down = true;
break;
}
}
public void minusDirection(KeyEvent e){
switch(e.getKeyCode()){
//keyEvent.VK_可以找到键的打印值
case KeyEvent.VK_LEFT:
left = false;
break;
case 38:
up = false;
break;
case 39:
right = false;
break;
case 40:
down = false;
break;
}
}
}
Explode(爆炸)类:
package game;
import java.awt.*;
public class Explode{
double x,y;
Image boom = GameUtil.getImage("images/图片1.png");
public void drawBoom(Graphics g){
g.drawImage(boom, (int) x, (int) y, null);
}
public Explode(double x ,double y){
this.x = x;
this.y = y;
}
}
最后就是导入图片啦,我的图片都是从网上下载,然后自己拿作图工具稍微改了改,大家可以选择自己喜欢的图片。记得图片地址要写对哦~
最终效果图(两种提示方式):