java 炮打飞机_【Java小项目】打飞机

a665240772abb3fb1b5963982d1fbe47.png

主要功能:

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

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

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

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

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

遇到的问题:

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

y+=speed;

if(left&&x-speed>0)

x-=speed;

if(right&&x+speed

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

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

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;

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值