前言:
“前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默
经过小新缜密的思考与亲身体验,忍不住分享一下给大家。有人工智能兴趣的朋友们,推荐大家一起学习 点击直接访问
里面有丰富的人工智能学习资料,真正做到从入门到入土,还不快来一起学习
个人名片:
作者简介:一名大一在校生
❄️个人主页:小新爱学习.
个人WeChat:hmmwx53
️系列专栏:零基础学java ----- 重识c语言
每日一句:青山一片云雾心安即归处。
首先,要把整体的游戏框架和内容构思出来(根据预先构思游戏里存在的组件内容和游戏功能抽象出指定类)。以我的小游戏为例:
1.主界面框架类:
显示开始界面
2.弹出界面类:
JDialog 窗体的功能是从一个窗体中弹出另一个窗体,就像是在使用 IE 浏览器时弹出的确定对话框,JDialog 窗体与 JFrame 窗体形式基本相同,设置窗体的特性时调用的方法名称都基本相同,如设置窗体大小、窗体关闭状态等
3.游戏面板类:GamePanel (extends JPanel)
真正显示飞机大战动态游戏画面,并且还添加了按钮JButton用于控制游戏开始暂停。
4.玩家飞机类:Hero
移动玩家飞机、画玩家飞机等其他与玩家飞机相关的方法
5.敌机类:AirPlane
移动敌机、画敌机
6.子弹类
移动子弹、绘制子弹
7碰撞类:Collision
检测各种碰撞情况
8.主类:Main
开启程序
package cn.tede.shoot;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.TimerTask;
//import static java.util.concurrent.locks.StampedLock.STATE;
public class ShootGame extends JPanel {
public static final int WIDTH =400;
public static final int HEIGHT =654;
private int state;
public static final int START = 0;
public static final int RUNNING = 1;
public static final int PAUSE = 2;
public static final int GAME_OVER =4;
public static BufferedImage background;
public static BufferedImage start;
public static BufferedImage airplane;
public static BufferedImage bee;
public static BufferedImage bullet;
public static BufferedImage hero0;
public static BufferedImage hero1;
public static BufferedImage pause;
public static BufferedImage gameover;
private FlyingObject[] flyings = {}; //敌机数组
private Bullet [] bullets = {}; //子弹数组
private Hero hero = new Hero();//英雄鸡
private Timer timer;//定时器
private int intervel = 1000/100; //时间间隔,十毫秒
private int score = 0;//得分
// public ShootGame(){
flyings = new FlyingObject[2];
flyings[0] = new AirPlane();
flyings[1] = new Bee();
bullets = new Bullet[1];
bullets[0] = new Bullet(180,300);
// }
static{//静态代码块
try {
background= ImageIO.read(ShootGame.class.getResource("background.png"));
start= ImageIO.read(ShootGame.class.getResource("start.png"));
airplane = ImageIO.read(ShootGame.class.getResource("airplane.png"));
bee = ImageIO.read(ShootGame.class.getResource("bee.png"));
bullet = ImageIO.read(ShootGame.class.getResource("bullet.png"));
//bullet = ImageIO.read(ShootGame.class.getResource("B1.png"));
//hero0= ImageIO.read(ShootGame.class.getResource("C.png"));
hero0= ImageIO.read(ShootGame.class.getResource("hero0.png"));
hero1 = ImageIO.read(ShootGame.class.getResource("hero1.png"));
pause= ImageIO.read(ShootGame.class.getResource("pause.png"));
gameover = ImageIO.read(ShootGame.class.getResource("gameover.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void paint(Graphics g) {
g.drawImage(background,0,0,null);//画背景图片
paintHero(g);
paintBullets(g);
paintFlyingObject(g);
paintScore(g);//画分数
// paintPause(g);
paintState(g);
}
/**
* 画游戏状态
*
*/
public void paintState(Graphics g){
switch(state){
case START:
g.drawImage(start,0,0,null);
break;
case PAUSE:
g.drawImage(pause, 0, 0, null);
break;
case GAME_OVER:
g.drawImage(gameover, 0, 0, null);
break;
}
}
/**
* 画分数
* @param g
*/
public void paintScore(Graphics g){
Font font = new Font(Font.SANS_SERIF, Font.BOLD,4);
g.setColor(new Color(0xffff0));//设置字体
g.drawString("SCORE"+score,10,25);
g.drawString("LIFE"+hero.getLife(),10,45);
}
//画英雄鸡
public void paintHero(Graphics g){
g.drawImage(hero.getImage(),hero.getX(),hero.getY(),null);
}
//画子弹
public void paintBullets(Graphics g){
for(int i = 0;i < bullets.length; i++){
Bullet b = bullets[i];
g.drawImage(b.getImage(),b.getX(),b.getY(),null);
}
}
//画飞行物
public void paintFlyingObject(Graphics g){
for(int i = 0; i< flyings.length;i++){
FlyingObject f = flyings[i];
g.drawImage(f.getImage(),f.getX(),f.getY(),null);
}
}
// //画暂停
// public void paintPause(Graphics g){
// g.drawImage(pause,0,0,null);
// }
//随机生成飞行物
public static FlyingObject nextOne(){
//返回 飞行物对象
Random random = new Random();
int type = random.nextInt(20);//生成随机数0-19
if(type == 0){
return new Bee();
}else{
return new AirPlane();
}
}
int flyEnterIndex = 0;
//飞行物入场
public void enterAction () {
flyEnterIndex++;
if (flyEnterIndex % 40 == 0) {//每调用40次该方法
FlyingObject obj = nextOne();//随机生成一个飞行物
flyings = Arrays.copyOf(flyings, flyings.length + 1);//扩容
flyings[flyings.length - 1] = obj;//放在最后一位
}
}
/*
实现飞行物移动
*/
public void stepAction() {
for (int i = 0; i < flyings.length; i++){
FlyingObject f = flyings[i];
f.step();
}
for(int i = 0;i<bullets.length;i++){
/**
* 子弹走
*
*/
Bullet b = bullets[i];
b.step();
// bullets[i].step();
}
hero.step();
}
int shootIndex = 0;
//射击
public void shootAction() {
//调用30次该方法发射一次子弹,
//英雄级打出子弹
//扩容
//追加数组
shootIndex++;
if (shootIndex % 30 == 0) {//每调用30次该方法
Bullet [] bs = hero.shoot();//英雄鸡打出子弹
bullets = Arrays.copyOf(bullets, bullets.length + bs.length);//扩容
System.arraycopy(bs,0,bullets,bullets.length - bs.length,bs.length);
}
}
public void bangAction() {
for (int i = 0; i< bullets.length; i++){
Bullet b = bullets[i];
bang(b);
}
}
private void bang(Bullet bullet) {
int index = -1;
for (int i = 0; i <flyings.length;i++){
FlyingObject obj = flyings[i];
if(obj.shootBy(bullet)){
index = i;
break;
}
}
if(index != -1) {
//击中
FlyingObject one = flyings[index];//记录被击中的飞行物
FlyingObject temp = flyings[index];//被击中的飞行物与最后一个飞行物交换
flyings[index] = flyings[flyings.length - 1];
flyings[flyings.length - 1] = temp;
//删除最后一个飞行物(被击中的飞行物)
flyings = Arrays.copyOf(flyings, flyings.length - 1);
//检测one的类型,若果是敌人就加分
if (one instanceof Enemy) {
Enemy e = (Enemy) one;
score += e.getScore();
}
if (one instanceof Award) {
Award a = (Award) one;
int type = a.getType();
switch (type) {
case Award.DOUBLE_FIRE:
hero.addDoubleFire();
break;
case Award.LIFE:
hero.addLife();
break;
}
}
}
//如果one的类型就奖励,则设置奖励
}
/**
* 删除越界的飞行物和子弹,小蜜蜂,飞机
*/
public void outOfBoundsAction() {
int index = 0;
FlyingObject[] flyingLives = new FlyingObject[flyings.length];//没有碰撞的飞行物
for (int i = 0; i < flyings.length; i++) {
FlyingObject f = flyings[i];
if (!f.outOfBounds()) {
flyingLives[index++] = f;//没有越界的存储到或者的数组
}
}
flyings = Arrays.copyOf(flyingLives, index);//没有越界的都留着
index = 0;
Bullet[] bulletLives = new Bullet[bullets.length];//存储没有发生碰撞的子弹
for (int i = 0; i < bullets.length; i++) {
Bullet b = bullets[i];
if (!b.outOfBounds()) {//如果没有越界
bulletLives[index++] = b;
}
}
bullets = Arrays.copyOf(bulletLives,index);
}
/**
* 检测游戏是否结束
*/
public boolean isGameOver() {
for (int i = 0; i < flyings.length; i++) {//遍历所有飞行物
int index = -1;//没有发生碰撞
FlyingObject obj = flyings[i];
if(hero.hit(obj)){//检查英雄鸡与飞行物是否碰撞
hero.subtractLife();//减命
hero.setDoubleFire(0);//双倍火力清零
index = i;//将碰撞飞行物的下标给到index
}
if(index!=-1){
FlyingObject t = flyings[index];
flyings[index] = flyings[flyings.length - 1];
flyings[flyings.length - 1] = t;//发生碰撞的元素和最后一个元素交换
flyings = Arrays.copyOf(flyings,flyings.length-1);
}
}
return hero.getLife() <= 0;
}
/**
* 检查游戏是否结束
*/
public void checkGameOverAction() {
if(isGameOver()){//如果已经结束
state = GAME_OVER;//改变状态为结束
}
}
public void action(){
//鼠标监听事件
MouseAdapter i = new MouseAdapter(){
public void mouseMoved(MouseEvent e) {//鼠标移动
if(state == RUNNING) {
int x = e.getX();
int y = e.getY();
hero.moveTo(x, y);
}
}
public void mouseEntered(MouseEvent e){//鼠标进入
if(state == PAUSE){
state = RUNNING;
}
}
@Override
public void mouseExited(MouseEvent e) {//鼠标退出
if(state!=GAME_OVER&&state!=START){
state = PAUSE;//游戏装态不是GAMEOVER ,鼠标离开窗口 ,设置暂停
}
}
@Override
public void mouseClicked(MouseEvent mouseEvent) {
//鼠标点击事件
switch(state){
case START:
state = RUNNING;
break;
case GAME_OVER://当状态是结束的时候,点击鼠标,会重新初始化各个对象,状态变为开始
flyings = new FlyingObject[0];
bullets = new Bullet[0];
hero = new Hero();
score = 0;
state = START;
}
}
};
this.addMouseListener(i);//处理鼠标点击事件
this.addMouseMotionListener(i);//处理鼠标滑动操作
//启动执行代码
java.util.Timer timer = new java.util.Timer();
timer.schedule(new TimerTask() {
public void run() {
if(state == RUNNING){
enterAction();//飞行物入场
stepAction();//飞行物走一步
shootAction();
bangAction();
isGameOver();
checkGameOverAction();//检查游戏结束
outOfBoundsAction();
}
repaint();//重绘,调用paint方法
}
}, intervel ,intervel);//10毫秒以后,每隔10毫秒执行一次
}
public static void main(String[] args){
JFrame frame = new JFrame("飞机大战");//画框
ShootGame game = new ShootGame();
frame.add(game);
frame.setSize(WIDTH, HEIGHT);//窗口的大小
frame.setAlwaysOnTop(true);//窗口在最上边
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点x关闭
frame.setLocationRelativeTo(null);//设置窗体的初始记录
frame.setVisible(true);//尽快调用paint方法
game.action();
}
}
package cn.tede.shoot;
import java.awt.image.BufferedImage;
//英雄鸡
public class Hero extends FlyingObject {
BufferedImage[] images = {};
int index = 0;
private int doubleFire;//双倍火力的子弹数量
private int life;//命的数量
public Hero() {
life = 3;
doubleFire = 0;
this.image = ShootGame.hero0;
images = new BufferedImage[]{ShootGame.hero0, ShootGame.hero1};
width = image.getWidth();
height = image.getHeight();
x = 150;
y = 400;
}
@Override
public void step() {
if (images.length > 0) {
image = images[index++ / 10%images.length];
}
}
@Override
public boolean outOfBounds() {
return false;
}
@Override//重写
public boolean hitColumn() {
return false;
}
//发射子弹
public Bullet[] shoot() {
int xStep = width / 4;
int yStep = 20;
if (doubleFire > 0) {//双倍火力
Bullet[] bullets = new Bullet[5];//2
bullets[0] = new Bullet(x + xStep, y - yStep);
bullets[1] = new Bullet(x + 3 * xStep, y - yStep);
bullets[2] = new Bullet(x + 2 * xStep, y - yStep);
bullets[3] = new Bullet(x + 0 * xStep, y - yStep);
bullets[4] = new Bullet(x + 4 * xStep, y - yStep);
doubleFire -= 2;
return bullets;
} else {
Bullet[] bullets = new Bullet[1];
bullets[0] = new Bullet(x + 2 * xStep, y - yStep);
return bullets;
}
}
/**
*
* @param x:鼠标x坐标位置
* @param y;鼠标y坐标位置
*/
public void moveTo(int x, int y) {
this.x = x- width/2;//hero.x+width/2;
this.y = y - height/2;
}
public void addDoubleFire(){
doubleFire += 40;
}
public void addLife(){
life++;
}
//获取英雄鸡命数
public int getLife(){
return life;
}
// public boolean outOfBounds(){
// return false;
// }
//减命
public void subtractLife(){
life--;
}
//重新设计双倍火力值
public void setDoubleFire(int doubleFire){
this.doubleFire = doubleFire;
}
//碰撞的算法
public boolean hit(FlyingObject other){
int x1 = other.x - this.width/2 ;
int x2 = other.x + this.width/2 + this.width;
int y1 = other.y - this.height/2 ;
int y2 = other.y + other.height + other.height/2;
return this.x + this.width/2>x1
&&this.x+this.width/2<x2
&&this.y+this.height/2>y1
&&this.y+this.height/2<y2;
}
}
package cn.tede.shoot;
//父类
import java.awt.image.BufferedImage;
public abstract class FlyingObject {
protected int x;//x坐标
protected int y;//y坐标
protected int width;//宽
protected int height;//高
protected BufferedImage image;//图片
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public abstract void step();
public boolean shootBy(Bullet bullet){
int x= bullet.x;
int y = bullet.y;
return this.x<x&&x<this.x+width&&this.y<y && y<this.y+height;
}
/**
* 检查是否出界
* @return
*/
public abstract boolean outOfBounds();//
/**
* 检测是否碰墙
*/
public abstract boolean hitColumn();
}
package cn.tede.shoot;
/**
* 子弹
*/
public class Bullet extends FlyingObject{
private int speed = 3;//移动速度
public Bullet(int x,int y){
this.x = x;
this.y = y;
this.image = ShootGame.bullet;
}
@Override
public void step() {
y -= speed;
}
@Override
public boolean outOfBounds() {
return y<-height;
}
@Override
public boolean hitColumn() {
return y<-height;
}
}
package cn.tede.shoot;
import java.util.Random;
//蜜蜂
public class Bee extends FlyingObject implements Award{
private int xSpeed = 1;//x坐标的移动速度
private int ySpeed = 2;//y坐标的移动速度
private int awardType;//奖励类型
public Bee(){
this.image = ShootGame.bee;
width = image.getWidth();
height = image.getHeight();
y = - height;
//y = 200;
x= (int)Math.random()*(ShootGame.WIDTH - width);
Random r =new Random();
//int x = r.nextInt(ShootGame.WIDTH - width);
//x = 100;
awardType = r.nextInt(2);
}
@Override
public int getType() {//奖励类型
return awardType;
}
@Override
public void step() {
x+= xSpeed;
y+= ySpeed;
if(x>ShootGame.WIDTH - width){
xSpeed = -1;
}
if(x<0){
xSpeed = 1;
}
}
@Override
public boolean outOfBounds() {
return y>ShootGame.HEIGHT;
}
@Override
public boolean hitColumn() {
return false;
}
}
package cn.tede.shoot;
public class AirPlane extends FlyingObject implements Enemy{
private int speed = 2;//敌人飞机移动速度2
public AirPlane(){
this.image = ShootGame.airplane;
width = image.getWidth();
height = image.getHeight();
y= -height;
x = (int)(Math.random()*(ShootGame.WIDTH - width));
// x = 300;
// y = 190;
}
@Override
public int getScore() {
return 5;
}
@Override
public void step() {
y+=speed;
}
@Override
public boolean outOfBounds() {
return y>ShootGame.HEIGHT;
}
@Override
public boolean hitColumn() {
return y>ShootGame.HEIGHT;
}
}
package cn.tede.shoot;
/**
* 奖励
*/
public interface Award {
int DOUBLE_FIRE = 0;//双倍火力
int LIFE = 1;//一条命
/**
* 获得奖励的类型为上面的0或者1
* @return
*/
int getType();
}
ackage cn.tede.shoot;
/**
* 敌人
*/
public interface Enemy {
int getScore();
}
–
源码图片获取,微信私