zoukankan      html  css  js  c++  java
  • 【Java小项目】打飞机


    主要功能:

               1.w,a,s,d八个方向移动,j射击

               2.默认会右有5个敌机,敌机会有一个随机方向,并一直按着这个方向移动,碰到边界会发生反弹

               3.每个飞机只能发5个子弹,只有玩家的子弹才能对敌机造成伤害。

               4.用ArrayList存放子弹,repaint的时候遍历重绘

               5.用ConcurrentHashMap存放飞机,用HaskMap的话,当遍历的时候如果改变HaskMap的元素的话就会有一个Concurrent异常,而ConcurrentHashMap会自己检查变化。

                 

    OSC@GIT地址:http://git.oschina.net/A_yes/PlaneGame


    遇到的问题:

                plane类:

                                 问题:在按键触发时执行,但是飞机的移动不顺滑即按住一个方向它会顿一下才继续向前。

                                 解决方法:给飞机类加个Runnable接口,用线程来处理飞机移动,给4个方向boolean标志。

    完整代码:

    package com.ztc.plane;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * Created by ztc on 15-11-29.
     */
    public class Plane implements Runnable{
        //坐标
        double x,y;
        double speed;
        Image img;
        //移动方向,存活状态
        boolean up,down,left,right,alive;
        //发射子弹数
        int bulletSum;
        String name;
    
        public void setUp(boolean up) {
            this.up = up;
        }
    
    
        public void setDown(boolean down) {
            this.down = down;
        }
    
    
        public void setLeft(boolean left) {
            this.left = left;
        }
    
    
        public void setRight(boolean right) {
            this.right = right;
        }
        public Plane(){}
    
    
        public void setAlive(boolean alive) {
            this.alive = alive;
        }
    
        public Plane(String path,double x,double y,double speed,String name){
            this.x=x;
            this.y=y;
            this.speed=speed;
            this.alive=true;
            this.name=name;
            img=Util.getImage(path);
    
        }
        public void draw(Graphics g){
            g.drawImage(img,(int)x,(int)y,null);
        }
    
        public void move(boolean up,boolean down,boolean left,boolean right){
            if(up&&y-speed>0)
                y-=speed;
            if(down&&y+speed<Constant.GrameHeight-new ImageIcon(img).getIconHeight())
                y+=speed;
            if(left&&x-speed>0)
                x-=speed;
            if(right&&x+speed<Constant.GrameWidht-new ImageIcon(img).getIconWidth())
                x+=speed;
        }
        public Rectangle getRect(){
            return new Rectangle((int)x,(int)y,new ImageIcon(img).getIconWidth(),new ImageIcon(img).getIconHeight());
        }
        public void boom(Graphics g) {
            for (int i = 3; i > 0; i--) {
                g.drawImage(Util.getImage("assets/boom0" + i + ".png"), (int) x, (int) y, null);
            }
        }
    
        public int getBulletSum() {
            return bulletSum;
        }
    
        public void setBulletSum(int bulletSum) {
            this.bulletSum = bulletSum;
        }
    
        public Bullet shot(){
            Bullet bullet=null;
            if(alive&&bulletSum<Constant.BulletSum) {
                bullet = new Bullet("assets/bullet02.png", (int) x - 7 + new ImageIcon(img).getIconWidth() / 2, (int) y-15, Constant.BulletSpeed, 0.5,name);
                new Thread(bullet).start();
                bulletSum++;
            }
            return bullet;
        }
    
        @Override
        public void run() {
            while(true){
                move(up,down,left,right);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
                   Enemy类:

                                       Enemy类继承Plane类,所以它的移动只要重写run函数。

                                       随机角度:double o=new Random().nextDouble()*Math.PI*2;

                                   问题:遇到边界后镜面反弹;

                                             解决方法:以随机出来的方向与垂直向下的方向的夹角为要计算的角度,显然若碰到垂直的边则o= Math.PI*2-o碰到水平方向则o=Math.PI-o;

    完整代码:

    package com.ztc.plane;
    
    import javax.swing.*;
    import java.util.Random;
    
    /**
     * Created by ztc on 15-11-30.下午1:22
     */
    public class Enemy extends Plane{
        //轨迹
        String track;
        double o=new Random().nextDouble()*Math.PI*2;
        public Enemy(){}
        public Enemy(String path,double x,double y,double speed,String name,String track){
            super(path,x,y,speed,name);
            this.track=track;
        }
        //随机方向,遇边镜面反射
        public void myTrack(){
            x-=speed*Math.sin(o);
            y-=speed*Math.cos(o);
            if(x<0||x>Constant.GrameWidht-new ImageIcon(img).getIconWidth()){
                o= Math.PI*2-o;
            }
            if(y<0||y>Constant.GrameHeight-new ImageIcon(img).getIconHeight()-100){
                o=Math.PI-o;
            }
        }
        public void run(){
            while(true){
                myTrack();
                if(alive&&bulletSum<Constant.BulletSum) {
                    Bullet bullet = new Bullet("assets/bullet01.png", (int) x - 7 + new ImageIcon(img).getIconWidth() / 2, (int) y + new ImageIcon(img).getIconHeight(), Constant.BulletSpeed, 0,name);
                    new Thread(bullet).start();
                    Util.bullets.add(bullet);
                    bulletSum++;
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

                       Bullet类:

                                     问题:刚开始时把移动写了一个方法在repaint的时候调用,速度很怪异

                                     解决:加Runnable借口,移动写在run里

    package com.ztc.plane;
    
    import javax.swing.*;
    import java.awt.*;
    import java.util.Random;
    
    /**
     * Created by ztc on 15-11-29.下午12:35
     */
    public class Bullet implements Runnable{
        //坐标
        double x=200,y=200;
        double speed;
        Image img;
        //方向(0,1)
        double direct;
        double o=new Random().nextDouble()*Math.PI*2;
        boolean alive;
        String owner;
        public boolean isAlive() {
            return alive;
        }
    
        public void setAlive(boolean alive) {
            this.alive = alive;
        }
    
        public Bullet(){
        }
        public Bullet(String path,double x,double y,double speed,double direct,String owner){
            this.x=x;
            this.y=y;
            this.speed=speed;
            this.direct=direct;
            this.alive=true;
            this.owner=owner;
            img=Util.getImage(path);
        }
        public void draw(Graphics g){
            g.drawImage(img,(int)x,(int)y,null);
        }
    
        public String getOwner() {
            return owner;
        }
        //随机方向,遇边镜面反射
        public void drawRandom(Graphics g){
            g.drawImage(img,(int)x,(int)y,null);
            x-=speed*Math.sin(o);
    
            y-=speed*Math.cos(o);
            if(x<0||x>Constant.GrameWidht){
                o=Math.PI*2-o;
            }
            if(y<0||y>Constant.GrameHeight){
                o=Math.PI-o;
            }
        }
        public Rectangle getRect(){
            return new Rectangle((int)x,(int)y,new ImageIcon(img).getIconWidth(),new ImageIcon(img).getIconHeight());
        }
    
        @Override
        public void run() {
            while(true){
                x+=speed*Math.sin(direct*Math.PI*2);
                y+=speed*Math.cos(direct*Math.PI*2);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(y<0||x<0||y>Constant.GrameHeight||x>Constant.GrameWidht) {
                    alive=false;
                    break;
                }
            }
        }
    }
    




     

  • 相关阅读:
    汇编(一)续
    汇编(一)
    Ubuntu 安装配置Dosbox
    Linux系统安装Dos系统(虚拟机里装)
    .bundle文件如何安装
    Linux(Fedora)系统下配制8086汇编环境
    Linux常用命令
    linux下安装nginx
    缓存雪崩、缓存穿透、缓存击穿是什么?如何解决?
    Maven 实战
  • 原文地址:https://www.cnblogs.com/A-yes/p/9894218.html
Copyright © 2011-2022 走看看