这些天,我不是很想复习专业课,想打游戏,但是吧,我想我说是个程序员预备役,但是还没自己写过一个小游戏,一直都是做网页开发,搞搞业务逻辑,不妨试试做个游戏?? 我在开始之前其实是有思路的,游戏的效果,就是后台逻辑控制出来的,先不谈3D或者其他的复杂的,我感觉如此。就是张图片,然后有攻击力度和敌人的血量,打一下调多少血,或者没血了,敌人消失。我们把敌人图片从游戏界面删除即可。 (其实应该不是那么简单的吧。 那么子弹也要飞的,子弹和敌人碰到,敌人也会减命的这是子弹的行为 这部分不算难,只要前面的理解了,这部分的思路很清晰的身无分文宅家,细发日渐稀疏。 双亲日益劳累,奈何无心寻工。 复试遥遥无期,心情惨惨戚戚。 若问此时作甚?抽烟喝酒扣叮。 ---杂记 2020/3/25-2020/4/12
矫情下,莫认真
接下来奉上近日学习内容
ok这也是本人的一幅作品,有兴趣的同学可以下。。。。
哈哈哈哈
各位大神有空可在评论区当面打我脸,本人欢迎。)
那么放在Java中这个敌人吧,我们可以抽象个类。
然后一个界面里面肯定不止有一个敌人,这是肯定的,那么我们就需要一个容器去存储在界面上有效的敌人,然后当敌人无效时(无效就是说敌人被打死,或者说敌人不在游戏界面我们打不到时),我们将无效的敌人对象删除。
ok,我们再来分析下我们的大业务
英雄机———-我们的主角
敌人————–小型敌人(一个5分,血量为1),中型敌人(20分之一的概率一个20分,血量为4),大型敌人(满1000出现一个,且血量随着1000的出现而上涨最低为8,一个得20分).‘’奖励敌人‘’(给双倍火力,或者是加一条命)
业务流程没啥好说的,就跟微信我们玩过的一样,见到打就是,然后看最后的得分,和敌人碰到就死,敌人不会发子弹(MD要是敌人会发子弹,我这游戏水平,根本打不到1000分。我是菜鸡,自己弄得游戏也打不好,虽然我可以不死,但这不就没意思了嘛。 )
说句题外话,后面两个敌人一开始是没有的,我随便打,就没死过,除非故意。
但是加上中型还好,加上大型的之后。吼吼吼没超过5000分。。。
到目前为止
我们分析了有,英雄机,3个敌人,1个‘’奖’励敌人‘’,一共5个实体了吧
那么问题来了
请问,子弹算不算一个实体?
说是英雄机可以装子弹,但是这是游戏,它的子弹是我们给他画出来的。于是,根据找类的原则:需要维护一定的状态和有一定的行为
子弹的状态是,它的飞行速度和他的图片。
OK
我们接下来再提取几个公共的功能,抽象出来一个父类。他们都会飞,自己的飞机,子弹和所有敌人都是可以飞的,除了自己的飞机,是由鼠标控制的之外,其他的都有飞行这一选项,
我们用程序模拟这些除自己的飞机之外的类飞行,就是在面板上定时移动其图片,给人感觉他就在移动一样——(是不是说破了就很无聊。。。)
注意了子弹是从下往上打的,敌人是从上往下落的,所以我们对于这个方法,我们要给他声明为抽象方法,然后我们在各自的类进行不同的实现。
对于敌人我们统一再声明个接口,里面存放,敌人生命是否已死,以及得分。这样也方便我们以后添加新的敌人。
对于‘’奖励敌人‘’也是
我们声明一个接口,然后实现该接口,方便日后新增‘’奖励敌人‘’。下面就是这些类的具体实现啦。
首先是接口和父类
import java.awt.image.BufferedImage; public abstract class FlyingObject { /* * 位置x,y, 大小width length 图片image 每个对象都有这些东西,所以给抽象称父类 */ protected BufferedImage image; protected int width; protected int height; protected int x; protected int y; /** * 飞行物起飞 */ public abstract void step(); /** * 检查是否出界 * * @return true 越界,false不越界 */ public abstract boolean outOfBounds(); /** * 敌人被子弹射 this 代表敌人,bullet是子弹 */ public boolean shootBy(Bullet bullet) { int x1 = this.x; int x2 = x1 + this.width; int y1 = this.y; int y2 = this.y + this.height; int x = bullet.x; int y = bullet.y; return x > x1 && x < x2 && y > y1 && y < y2; } } public interface Enemy { // 只要是敌人就能得分,小鸡5分,Boss20分 public int getScore(); public void subtractLife(); public boolean isDie(); public int getLife(); } public interface Award { // 双倍火力值 public int DOUBLE_FILE = 0; public int LIFE = 1; // 获取奖励类型 public int getType(); }
这是各类实体的具体实现
import java.awt.image.BufferedImage; import java.util.Random; public class Hero extends FlyingObject { // 命 private int life; // 火力值 private int doubleFire; // 图片数组 private BufferedImage[] images; // 协助图片切换 private int index; // 构造方法 public Hero() { image = PlaneGame.hero1; width = image.getWidth(); height = image.getHeight(); x = 150; y = 400; life = 3; doubleFire = 0; images = new BufferedImage[2]; images[0] = PlaneGame.hero0; images[1] = PlaneGame.hero1; index = 0; } @Override public void step() { // 10ms走一次 // 100ms换一张图 /* * index++; int a=index/10; int b=a%2; image=images[b]; */ image = images[index++ / 10 % images.length]; } /** * 英雄机发射子弹 */ public Bullet[] shoot() { int xStep = this.width / 4; if (doubleFire > 0) { Bullet[] bs = new Bullet[2]; bs[0] = new Bullet(x + xStep, y); bs[1] = new Bullet(x + (3 * xStep), y); doubleFire -= 2; return bs; } else if (doubleFire <= 0) { Bullet[] bs = new Bullet[1]; bs[0] = new Bullet(x + 2 * xStep, y); return bs; } return null; } /** * * @param x * @param y */ public void moveTo(int x, int y) { this.x = x - this.width / 2; this.y = y - this.height / 2; } @Override public boolean outOfBounds() { // TODO 自动生成的方法存根 return false; } /** * 英雄机加命 */ public void addLife() { life++; } /** * 获取命 * * @return */ public int getLife() { return life; } /** * 减命 */ public void subtractLife() { life--; } /** * 英雄机加火力值 */ public void addDoubleFire() { doubleFire += 40; } public void clearDoubleFire() { doubleFire = 0; } public boolean hit(FlyingObject obj) { int x1 = obj.x - this.width / 2; int x2 = obj.x + obj.width + this.width / 2; int y1 = obj.y - this.height / 2; int y2 = obj.y + obj.height + this.height / 2; int x = this.x + this.width / 2; int y = this.y + this.height / 2; return x > x1 && x < x2 && y < y2 && y > y1; } public boolean isDie() { // TODO 自动生成的方法存根 return life == 0; } } import java.util.Random; public class Airplane extends FlyingObject implements Enemy { private int speed = 2;// 走步的步数 public int life = 1; // 构造方法 public Airplane() { image = PlaneGame.airplane; width = image.getWidth(); height = image.getHeight(); Random rand = new Random(); // x位于0到窗口宽-敌机宽之间的随机数 x = rand.nextInt(PlaneGame.WIDTH - this.width); y = -this.height; } @Override public int getScore() { // 打掉一个敌机得5分 life--; return 5; } @Override public void step() { y = y + speed;// 敌机向下坠 } public boolean isDie() { return life <= 0; } public void subtractLife() { life--; } @Override public boolean outOfBounds() { return this.y >= PlaneGame.HEIGHT; } @Override public int getLife() { // TODO 自动生成的方法存根 return life; } } import java.util.Random; public class Boss extends FlyingObject implements Enemy { public int life; private int speed; public Boss() { this.life = 5; this.speed = 1; image = PlaneGame.boss; height = image.getHeight(); width = image.getWidth(); Random rand = new Random(); // x位于0到窗口宽-敌机宽之间的随机数 x = rand.nextInt(PlaneGame.WIDTH - this.width); y = -this.height; } @Override public int getScore() { // TODO 自动生成的方法存根 return 30; } public boolean isDie() { return life <= 0; } public void subtractLife() { life = life - 1; } @Override public void step() { // TODO 自动生成的方法存根 y = y + speed; } @Override public boolean outOfBounds() { return this.y >= PlaneGame.HEIGHT; } @Override public int getLife() { // TODO 自动生成的方法存根 return life; } } import java.util.Random; public class BigBoss extends FlyingObject implements Enemy { public int life = 10; public int speed; public BigBoss(int k) { this.life = this.life * k; this.speed = 1; image = PlaneGame.bigboss; height = image.getHeight(); width = image.getWidth(); Random rand = new Random(); // x位于0到窗口宽-敌机宽之间的随机数 x = rand.nextInt(PlaneGame.WIDTH - this.width); y = -this.height; } @Override public int getScore() { // TODO 自动生成的方法存根 return 200; } @Override public void subtractLife() { life = life - 1; } @Override public boolean isDie() { // TODO 自动生成的方法存根 return life <= 0; } @Override public int getLife() { // TODO 自动生成的方法存根 return life; } @Override public void step() { if (y < 0) { y = y + speed; } else { y = y; } } @Override public boolean outOfBounds() { // TODO 自动生成的方法存根 return false; } } import java.util.Random; public class Bee extends FlyingObject implements Award { // x坐标的走步步数 private int xSpeed = 1; // y坐标走步步数 private int ySpeed = 2; // 奖励类型 private int awardType; public int life; // 构造方法 public Bee() { life = 1; image = PlaneGame.bee; width = image.getWidth(); height = image.getHeight(); Random rand = new Random(); // x位于0到窗口宽-敌机宽之间的随机数 x = rand.nextInt(PlaneGame.WIDTH - this.width); y = -this.height; awardType = rand.nextInt(2); } @Override public int getType() { life--; return awardType; } public boolean isDie() { return life == 0; } @Override public void step() { x = x + xSpeed; y = y + ySpeed; if (x >= PlaneGame.WIDTH - this.width) { // 到窗口最右边,弹回来 xSpeed = -1; } if (x <= 0) { // 到最左边,弹回来 xSpeed = 1; } } @Override public boolean outOfBounds() { // TODO 自动生成的方法存根 return this.y >= PlaneGame.HEIGHT; } } import java.util.Random; public class Bullet extends FlyingObject { // 走步步数 private int speed = 3; // 构造方法 // 子弹的x,y根据英雄机走 public Bullet(int x, int y) { image = PlaneGame.bullet; width = image.getWidth(); height = image.getHeight(); this.x = x; this.y = y; } @Override public void step() { // 子弹向上飞 y = y - speed; } @Override public boolean outOfBounds() { // TODO 自动生成的方法存根 return (this.y + this.height) <= 0; } public boolean isDie() { // TODO 自动生成的方法存根 return false; } }
接下来就是业务流程
具体的业务流程在代码注释里,我写的很清楚哦package com.jjyu.shoot; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.File; import java.util.Arrays; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; public class PlaneGame extends JPanel { // 窗口宽 public static final int WIDTH = 400; // 窗口高 public static final int HEIGHT = 654; // 背景图 public static BufferedImage background; // 启动图 public static BufferedImage start; // 暂停图 public static BufferedImage pause; // 结束 public static BufferedImage gameover; // 敌机 public static BufferedImage airplane; // Boss飞机 public static BufferedImage boss; //1000分后的超大飞机 public static BufferedImage bigboss; // 蜜蜂 public static BufferedImage bee; // 子弹 public static BufferedImage bullet; // 英雄机0 public static BufferedImage hero0; // 英雄机1 public static BufferedImage hero1; // 开始状态 public static final int START = 0; // 运行状态 public static final int RUNNING = 1; // 暂停状态 public static final int PAUSE = 2; // 结束状态 public static final int GAME_OVER = 3; // 当前默认状态 private int state = START; // 英雄机对象 private Hero hero = new Hero(); // 敌人机数组 private FlyingObject[] flyings = {}; // 子弹数组 private Bullet[] bullets = {}; public PlaneGame() { } static { // 初始化静态资源(图片) try { // File file=new File(""); // ImageIO.read(file); background = ImageIO.read(PlaneGame.class .getResource("background.png")); start = ImageIO.read(PlaneGame.class.getResource("start.png")); pause = ImageIO.read(PlaneGame.class.getResource("pause.png")); gameover = ImageIO .read(PlaneGame.class.getResource("gameover.png")); airplane = ImageIO .read(PlaneGame.class.getResource("airplane.png")); bee = ImageIO.read(PlaneGame.class.getResource("bee.png")); boss = ImageIO.read(PlaneGame.class.getResource("boss.png")); bigboss=ImageIO.read(PlaneGame.class.getResource("bigboss.png")); bullet = ImageIO.read(PlaneGame.class.getResource("bullet.png")); hero0 = ImageIO.read(PlaneGame.class.getResource("hero0.png")); hero1 = ImageIO.read(PlaneGame.class.getResource("hero1.png")); } catch (Exception e) { e.printStackTrace(); } } /** * 满1000分来个大Boss * @return 10分之2的概率产生小蜜蜂,20分之1的概率产生大Boss,10分之7的概率产生敌机 */ public FlyingObject nextOne() { if(score!=0&&score%1000==0){ return new BigBoss(score/1000); } Random rand = new Random(); int type = rand.nextInt(200); if (type <= 20) { return new Bee(); } else if (type <= 30) { return new Boss(); } else { return new Airplane(); } } // 敌人入场计数器 int flyEnteredIndex = 0; /** * 生成敌人对象,将对象添加到flying数组中 敌人入场 */ protected void enterAction() { flyEnteredIndex++; if (flyEnteredIndex % 40 == 0) { // 400毫秒走一次 FlyingObject one = nextOne(); // 敌人数组扩容 flyings = Arrays.copyOf(flyings, flyings.length + 1); // 将敌人放在数组最后 flyings[flyings.length - 1] = one; } } /** * 英雄机发射子弹 */ int shootIndex = 0; protected void shootAction() { shootIndex++; if (shootIndex % 30 == 0) { // 300ms一发子弹 Bullet[] bs = hero.shoot(); bullets = Arrays.copyOf(bullets, bullets.length + bs.length); // for(int i=0;i<bs.length;i++){ // bullets[bullets.length-i-1]=bs[i]; // } // 数组的追加 System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length); } } /** * 飞行物飞,10ms走一步 */ protected void stepAction() { hero.step(); for (int i = 0; i < flyings.length; i++) { flyings[i].step(); } for (int i = 0; i < bullets.length; i++) { bullets[i].step(); } } /** * 删除越界敌人和子弹 */ protected void outOfBoundsAction() { // 不越界的敌人个数 int index = 0; FlyingObject[] flyingLives = new FlyingObject[flyings.length]; for (int i = 0; i < flyings.length; i++) { if (!flyings[i].outOfBounds()) { flyingLives[index] = flyings[i]; index++; } } // System.out.println(index); flyings = Arrays.copyOf(flyingLives, index); index = 0; Bullet[] b = new Bullet[bullets.length]; for (Bullet btemp : bullets) { if (!btemp.outOfBounds()) { b[index] = btemp; index++; } } // System.out.println(index); bullets = Arrays.copyOf(b, index); } /** * 所有子弹与所有敌人的碰撞 */ protected void bangAction() { for (int i = 0; i < bullets.length; i++) { // 获取每一个子弹 Bullet b = bullets[i]; int lenBefore = flyings.length; // 1个子弹和所有敌人的碰撞 // 说明子弹被用啦 if (bang(b)) { bullets[i] = bullets[bullets.length - 1]; bullets[bullets.length - 1] = b; bullets = Arrays.copyOf(bullets, bullets.length - 1); i--; } } } /** * 1个子弹与所有敌人的碰撞 * * @param b */ // 得分 int score = 0; protected boolean bang(Bullet b) { int index = -1; for (int i = 0; i < flyings.length; i++) { FlyingObject f = flyings[i]; if (f.shootBy(b)) { // 获取被撞的敌人坐标 index = i; break; } } if (index != -1) { // 获取被撞的敌人 FlyingObject one = flyings[index]; if (one instanceof Enemy) { Enemy e = (Enemy) one; // 玩家加分 System.out.println(e.getLife()); e.subtractLife(); System.out.println(e.getLife()); if(e.isDie()){ System.out.println(e.getLife()); score += e.getScore(); // 将被撞敌人与数组最后一个元素交换 FlyingObject t = flyings[index]; flyings[index] = flyings[flyings.length - 1]; flyings[flyings.length - 1] = t; // 缩容 flyings = Arrays.copyOf(flyings, flyings.length - 1); } } if (one instanceof Award) { Award a = (Award) one; int type = a.getType(); switch (type) { case Award.LIFE: hero.addLife(); break; case Award.DOUBLE_FILE: hero.addDoubleFire(); break; } // 将被撞敌人与数组最后一个元素交换 FlyingObject t = flyings[index]; flyings[index] = flyings[flyings.length - 1]; flyings[flyings.length - 1] = t; // 缩容 flyings = Arrays.copyOf(flyings, flyings.length - 1); } return true; } return false; } /** * 检查游戏结束 */ protected void checkGameOverAction() { // TODO 自动生成的方法存根 if (isGameOver()) { state = GAME_OVER; } } /** * 是否游戏结束 返回true则游戏结束 * * @return */ public boolean isGameOver() { for (int i = 0; i < flyings.length; i++) { FlyingObject f = flyings[i]; if (hero.hit(f)) { hero.subtractLife(); hero.clearDoubleFire(); // 被撞后敌人数组的变化 flyings[i] = flyings[flyings.length - 1]; flyings = Arrays.copyOf(flyings, flyings.length - 1); i--; } } return hero.getLife() <= 0; } public void action() { // 创建侦听器对象 MouseAdapter l = new MouseAdapter() { /** * 重写鼠标移动事件 * * @param e */ public void mouseMoved(MouseEvent e) { if (state == RUNNING) { // 英雄机随便动 // 获取鼠标的x坐标 int x = e.getX(); // 获取鼠标的y坐标 int y = e.getY(); hero.moveTo(x, y); } } /** * 重写鼠标移出事件 */ public void mouseExited(MouseEvent e) { if (state == RUNNING) state = PAUSE; } /** * 重写鼠标移入事件 */ public void mouseEntered(MouseEvent e) { if (state == PAUSE) { state = RUNNING; } } public void mouseClicked(MouseEvent e) { switch (state) { case START: state = RUNNING; break; case GAME_OVER:// 游戏结束状态前 // 所有数据归0 score = 0; hero = new Hero(); flyings = new FlyingObject[0]; bullets = new Bullet[0]; state = START; break; } } }; // 鼠标操作事件 this.addMouseListener(l); // 鼠标移动事件 this.addMouseMotionListener(l); Timer timer = new Timer(); int intervel = 10;// 时间间隔,毫秒为单位 timer.schedule(new TimerTask() { @Override public void run() { if (state == RUNNING) { shootAction();// 子弹入场 // 定时干的那个事,每10个毫秒的事 enterAction(); // 飞行物定时飞 stepAction(); // 删除越界的敌人和子弹 outOfBoundsAction(); // 子弹与敌人撞 bangAction(); // 检查游戏是否结束 checkGameOverAction(); } repaint(); } }, intervel, intervel); } @Override // g当做画笔 public void paint(Graphics g) { // 画背景图 g.drawImage(background, 0, 0, null); // 画英雄机 paintHero(g); // 画子弹对象 paintBullets(g); // 画敌人对象 paintFlyingObjects(g); // 画分和命 paintScoreAndLife(g); // 画状态 paintState(g); } /** * 画状态 * * @param 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); } } public void paintHero(Graphics g) { // 画英雄机 g.drawImage(hero.image, hero.x, hero.y, null); } public void paintBullets(Graphics g) { // 画子弹对象 for (int i = 0; i < bullets.length; i++) { Bullet b = bullets[i]; g.drawImage(b.image, b.x, b.y, null); } } public void paintFlyingObjects(Graphics g) { // 画敌人(敌机,小蜜蜂)对象 for (int i = 0; i < flyings.length; i++) { FlyingObject fo = flyings[i]; g.drawImage(fo.image, fo.x, fo.y, null); } } /** * 画英雄机得分和命 * * @param g */ public void paintScoreAndLife(Graphics g) { g.setColor(new Color(0xffff00)); g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20)); g.drawString("得分: " + score, 10, 600); g.drawString("飞机复活次数: " + hero.getLife(), 10, 580); } public static void main(String[] args) { // 创建了框架,窗口 JFrame frame = new JFrame("Fly"); // 创建了面板 PlaneGame game = new PlaneGame(); // 向窗口中加入面板 frame.add(game); // 设置窗口的大小 frame.setSize(WIDTH, HEIGHT); // 设置是否总在顶部 frame.setAlwaysOnTop(true); // 设置默认关闭,关闭窗口时,退出程序 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置相对位置为null时居中,否则在屏幕的定点 frame.setLocationRelativeTo(null); // 1、设置窗口可见 2、尽快调用paint()方法 frame.setVisible(true); // 启动程序执行 game.action(); } }
素质三连啊,小伙伴们。
素质三连》》》
,关注,》》》》
三连。
阅读辛苦。再走
skr~~
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算