Java原创创意,自制素材,加音效坦克大战,原创up主游戏,较完整简单版1【诗书画唱】
























package 坦克大战完整版;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import java.util.*;
//这个来做绘制内容,发射子弹一类的操作
//让这个类实现键盘点击的接口
public class caoZuo extends JPanel implements KeyListener,Runnable{
//在构造法方法里实例化我方坦克
// arraylist:存储任意类型,内容长度任意,有下标
Vector<diRenTanKe> diRenTanKeVector
=new Vector<diRenTanKe>();
myTanKe myTanKe=null;
public caoZuo(){
myTanKe=new myTanKe(150,440,0);
for(int i=0;i<5;i++){
diRenTanKe d=new diRenTanKe(100*i, 0, 2);
diRenTanKeVector.add(d);
Thread Thread=new Thread(d);
Thread.start();
}
}
//绘制的方法
public void paint(Graphics g){
g.setColor(Color.black);
g.fillRect(0,0,600,600);
g.setColor(Color.green);
//上:
huiZhiTanKeFangFa(g,myTanKe.TanKeFuLeiX,
myTanKe.TanKeFuLeiY,0,
myTanKe.TanKeFuLeiFangXiang);
//点击J键,myTanK写坦克的方法,判断其方式,绘制子弹
//遍历子弹的集合,子弹有几发就绘制几发
for(int i=0;i<myTanKe.v.size();i++){
ziDanClass z=myTanKe.v.get(i);
//得到每一发子弹
//说明这个子弹是存在的,
// 并且子弹的生命为真的时候才绘制子弹
if(z!=null&&z.shengMing){
g.fillRect(z.x,z.y,10,10);
}
//如果子弹的生命为false,也就是子弹达到了页面的边界
//就移除该子弹
if(!z.shengMing){
myTanKe.v.remove(z);
}
}
//遍历刚才存入的5个敌方坦克
for(int i=0;i<diRenTanKeVector.size();i++){
diRenTanKe diRenTanKe
=diRenTanKeVector.get(i);
if(diRenTanKe!=null&&diRenTanKe.shengMing){
huiZhiTanKeFangFa(g,diRenTanKe.TanKeFuLeiX,
diRenTanKe.TanKeFuLeiY,1,diRenTanKe.TanKeFuLeiFangXiang);
}
if(diRenTanKe!=null&&diRenTanKe.shengMing){
//得到坦克的子弹
Vector<ziDanClass> v_zidan=diRenTanKe.v;
//遍历每个坦克的地方子弹
for(ziDanClass j:v_zidan){
//如果每个子弹确实存在并且每个子弹的生命为真就可以
//绘制子弹了
if(j!=null&&j.shengMing){
g.fillRect(j.x, j.y, 10,10);
}
}
}
}
}
//封装坦克的方法
// 1.画笔 2.x 3.y 4.坦克的类型 5.坦克的方向
public void huiZhiTanKeFangFa(Graphics g,int x,int y,int leixing,int fangxiang){
//在这个方法里既可以绘制我方坦克,也可以绘制
//敌方TanK,TanK的类型就是判断是绘制什么颜色的坦克
switch(leixing){
case 0:
//画我方坦克
g.setColor(Color.green);break;
case 1:
g.setColor(Color.yellow);break;
}
switch(fangxiang){
case 0://向上
g.fillRect(x, y, 10,30);
g.fillRect(x+10, y-10, 10,30);
g.fillRect(x+20, y, 10,30);
break;
case 1://向右
g.fillRect(x, y, 30,10);
g.fillRect(x+10, y+10, 30,10);
g.fillRect(x, y+20, 30,10);
break;
case 2://向下
g.fillRect(x, y, 10,30);
g.fillRect(x+10, y+10, 10,30);
g.fillRect(x+20, y, 10,30);
break;
case 3://向左
g.fillRect(x, y, 30,10);
g.fillRect(x-10, y+10, 30,10);
g.fillRect(x, y+20, 30,10);
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
//键盘按下的事件
public void keyPressed(KeyEvent e) {
//点击W键
if(e.getKeyCode()==KeyEvent.VK_W){
myTanKe.yidong(0);
}
if(e.getKeyCode()==KeyEvent.VK_S){
myTanKe.yidong(2);
}
if(e.getKeyCode()==KeyEvent.VK_A){
myTanKe.yidong(3);
}
if(e.getKeyCode()==KeyEvent.VK_D){
myTanKe.yidong(1);
}
//点击j的时候发射子弹111
if(e.getKeyCode()==KeyEvent.VK_J){
if(myTanKe.v.size()<=2){//v的大小已经为6 j
new Thread(new shengYin("blast.wav")).start() ;
myTanKe.kaipao(myTanKe.TanKeFuLeiFangXiang);
}
}
this.repaint();
}
private void jztk(TanKeFuLei t,ziDanClass z){
// ——————
// 下面的是用instanceof来判断
// z.x是所属的哪个子类(diRenTanKe
// 或myTanKe),用
// z.x>=t.x&&z.x<=t.x+35&&z.y>=t.y&&z.y<=t.y+35
// 来判断我的坦克的子弹是否击中了敌人的坦克。
// 如果打中了,就用z.shengMing=false;
// t.shengMing=false;
// 分别让我的坦克的子弹和敌人的坦克隐藏,就是不显示,
// 就是会消失。
if(t instanceof diRenTanKe){
if(z.x>=t.TanKeFuLeiX&&z.x<=t.TanKeFuLeiX+35&&z.y>=t.TanKeFuLeiY&&z.y<=t.TanKeFuLeiY+35){
// new Thread(new shengyin("hit.wav")).start() ;
z.shengMing=false;
t.shengMing=false;
}
}
//if(t instanceof myTanKe){
//
//
// if(z.x>=t.x&&z.x<=t.x+35&&z.y>=t.y&&z.y<=t.y+35){
//// new Thread(new shengyin("hit.wav")).start() ;
// z.shengMing=false;
// t.shengMing=false;
// }
// }
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void run() {
while(true){
//new Thread(new shengyin("start.wav")).start() ;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//如果我方坦克是存在的才可以发射子弹
if(myTanKe.shengMing&&myTanKe!=null){
//遍历所有的我方子弹:
for(int i=0;i<myTanKe.v.size();i++){
//如果遍历的子弹的生命值为true也就是这个子弹存在
//就遍历所有的地方坦克
if(myTanKe.v.get(i).shengMing){
//遍历所有的地方坦克
for(int j=0;j<diRenTanKeVector.size();j++){
//得到所有的敌方坦克
diRenTanKe d=diRenTanKeVector.get(j);
//执行击中坦克的方法
jztk(d,myTanKe.v.get(i));
//执行击中坦克的方法
// jztk(myRenTanKe,m.v.get(i));
}
jztk(myTanKe,myTanKe.z);
}
}
}
this.repaint();
}
}
}


package 坦克大战完整版;
import java.util.Random;
import java.util.Vector;
public class diRenTanKe extends TanKeFuLei implements Runnable{
//地方坦克子弹的集合
Vector<ziDanClass> v=new Vector<ziDanClass>();
//敌方坦克类也是继承坦克父类
public diRenTanKe(int x, int y, int fangxiang) {
super(x, y, fangxiang);
this.suDu=5;
}
@Override
public void run() {
while(true){
// try {
// Thread.sleep(200);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
yidong();
//在这个位置添加子弹
//当前坦克是存在的
if(this.shengMing){
ziDanClass z=null;
switch(TanKeFuLeiFangXiang){
case 0:
z=new ziDanClass(TanKeFuLeiX+10,TanKeFuLeiY-10,this.TanKeFuLeiFangXiang);break;
case 1:
z=new ziDanClass(TanKeFuLeiX+40,TanKeFuLeiY+10,this.TanKeFuLeiFangXiang);break;
case 2:
z=new ziDanClass(TanKeFuLeiX+10,TanKeFuLeiY+40,this.TanKeFuLeiFangXiang);break;
case 3:
z=new ziDanClass(TanKeFuLeiX-20,TanKeFuLeiY+10,this.TanKeFuLeiFangXiang);break;
}
//将子弹添加到子弹集合里
v.add(z);
Thread t=new Thread(z);
t.start();
}
}
}
private void yidong() {
Random r=new Random();
int shuzi=r.nextInt(4);
switch(shuzi){
case 0:
for(int i=0;i<30;i++){
if(this.TanKeFuLeiY>=10){
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.TanKeFuLeiY-=this.suDu;
}
this.TanKeFuLeiFangXiang=0;
}
break;
case 1:
for(int i=0;i<30;i++){
if(this.TanKeFuLeiX<=40){
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.TanKeFuLeiX+=this.suDu;
}
this.TanKeFuLeiFangXiang=1;
}
break;
case 2:
for(int i=0;i<30;i++){
if(this.TanKeFuLeiY<=500){
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.TanKeFuLeiY+=this.suDu;
}
this.TanKeFuLeiFangXiang=2;
}
break;
case 3:
for(int i=0;i<30;i++){
if(this.TanKeFuLeiX>=10){
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.TanKeFuLeiX-=this.suDu;
}
this.TanKeFuLeiFangXiang=3;
}
break;
}
}
}


package 坦克大战完整版;
import java.awt.Color;
import javax.swing.*;
public class mains extends JFrame{
public static void main(String[] args) {
// 主函数调用mains类,同时会调用出其中包含的构造方法:
new mains();
new Thread(new shengYin("start.wav")).start();
}
public mains(){
// 用来显示页面,设置页面的部分:
this.setLayout(null);
this.setSize(600,600);
this.setLocationRelativeTo(null);
// ————
caoZuo caoZuo=new caoZuo();
// 因为caoZuo中有画笔工具类Graphics,
// 类Graphics中有paint方法中自己写的内容。
// 所以设置caoZuo类就是设置caoZuo类中
// 画图中的页面会显示“g.setColor(Color.black);
// g.fillRect(0,0,600,600);”
// 黑色矩形等的大小,一般来说是设置
// caoZuo.setBounds(0,0,600,600)和
// 黑色矩形背景的大小相等的
caoZuo.setBounds(0,0,600,600);
//要想caoZuo中显示的界面上的所有内容都有键盘事件的话就要
//要把实例化好了的类caoZuo,添加到
//this.addKeyListener中的“()”中。
this.addKeyListener(caoZuo);
// ————
// 下面是开启线程的部分(当开启线程时,
// 就会调用线程中的run方法中所设置的内容)
// 在mains类等处中的构造方法中写开启线程的
// 部分时,就是先要实例化继承线程类B的类A,
// 之后要实例化把类A添加到“()”中的线程类B。
// 之后用start方法开启线程。
Thread Thread=new Thread(caoZuo);
Thread.start();
this.add(caoZuo);
// ————
// 用来显示页面,设置页面的部分:
this.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
// ————
}
}




package 坦克大战完整版;
import java.io.*;
import java.text.Format;
import javax.sound.sampled.*;
public class shengYin implements Runnable{
private String wenjianming;
public shengYin(String w){
this.wenjianming=w;
}
@Override
public void run() {
File File=new File(wenjianming);
AudioInputStream ais=null;
try {
ais=AudioSystem.getAudioInputStream(File);
AudioFormat af=ais.getFormat();
SourceDataLine sdl=null;
DataLine.Info dl=new DataLine.Info(SourceDataLine.class,af);
sdl=(SourceDataLine)AudioSystem.getLine(dl);
sdl.open(af);
sdl.start();
int len=0;
byte[] b=new byte[1024];
while(len!=-1){
len=ais.read(b,0,b.length);
if(len>=0){
sdl.write(b,0,len);
}
}
sdl.drain();
sdl.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}


package 坦克大战完整版;
//
//TanK英 [taŋk]美 [tæŋk]n.坦克;
//x,y
public class TanKeFuLei {
//这个TanKeFuLei为父类,敌人坦克和我的坦克
// 都是子类,继承TanKeFuLei这个父类的。
//x轴,y轴,方向,速度,生命
int TanKeFuLeiX,TanKeFuLeiY,TanKeFuLeiFangXiang;
int suDu=15;//坦克默认移动的速度为15px
boolean shengMing=true;//每个坦克默认都是存在的
public TanKeFuLei(int x,int y,int fangXiang){
// 很多变量是同名(可以所属不同类的变量命名不同,
// 这时就可不用this,只要把传的值和当前的值用“=”赋值就可以,
// 但变量名会变多),
// 但所属的类不同,这时要用this来区分(不区分,就可能报错)。
//每次用swich或构造方法等都是要用this(表示“当前类的”)来区分
// 同名的。
this.TanKeFuLeiX=x;
this.TanKeFuLeiY=y;
this.TanKeFuLeiFangXiang=fangXiang;
}
}

package 坦克大战完整版;
///111111
public class ziDanClass implements Runnable{
//x(子弹的x轴上方向的位移),
// y(子弹的y轴上方向的位移),
// fangXiang(子弹的方向),suDu(子弹移动的速度)
// ,shengMing(子弹的生命):
int x,y,fangXiang;
int suDu=15;
boolean shengMing=true;
//默认子弹是存在的,所以先让子弹的shengMing为true
// ————
// 下面是子弹类中声明的能够传值的构造方法,可以通过
// “包名.方法名(对应能够传值的构造方法声明的数据类型和个数,
// 顺序的
// 具体的值)”:
public ziDanClass(int x, int y, int fangxiang) {
this.x = x;
this.y = y;
this.fangXiang = fangxiang;
}
// ————
// 下面是在线程中的run方法中写的
// 当调用构造方法时,传的对应的fangxiang值(这里是设置为可
// 0,1,2,3)
// ,会执行对应的switch(this.fangXiang),进而会执行对应的
// 有对应的fangXiang
//case下面的内容等
//
// (当调用构造方法时,也会执行run方法中的内容)。
@Override
public void run() {
while(true){
try {
Thread.sleep(50);
switch(this.fangXiang){
case 0:
this.y-=this.suDu;break;
case 1:
this.x+=this.suDu;break;
case 2:
this.y+=this.suDu;break;
case 3:
this.x-=this.suDu;break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// ————
//下面是判断子弹是否达到边界,如果子弹到达页面的边界(600)
//将子弹的生命设置为false,也就是让子弹不再绘制。但这里把
// 600设置为500,让其消失等的效果等更明显等
if(this.x<=0||this.y<=0||this.x>=500||this.y>=500){
shengMing=false;
}
}
}
}

————————————————————
原创up飞人游戏:



package duiXiang;
import img.img;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import mains.mains;
public class 背景 extends duiXiangFuLeiFangFa {
private static BufferedImage images;
// 静态代码块
static {
images = img.loadImage("背景.png");
}
private int speed;// 速度
public int y1;// 第二张图片的坐标
public 背景() {
super(mains.quanJvWidth,
mains.quanJvHeight, 0, 0);
speed = 1;
y1 = -mains.quanJvHeight;
}
/*这里的图片的高要比窗口的高大一些,图片向上移动时会出问题 */
public void yiDongFangFa() {
y += speed;
y1 += speed;
if (y >= mains.quanJvHeight) {
y = -mains.quanJvHeight;
}
if (y1 >= mains.quanJvHeight) {
y1 = -mains.quanJvHeight;
}
}
@Override
public BufferedImage getImageFangFa() {
return images;
}
/*重写父类中的方法 */
@Override
public void paintObjectDuiXiangFangFa(Graphics g) {
g.drawImage(getImageFangFa(), x, y, null);
g.drawImage(getImageFangFa(), x, y1, null);
}
}


package duiXiang;
import img.img;
import java.awt.image.BufferedImage;
public class 封茗囧茵 extends duiXiangFuLeiFangFa
implements diRen{
// 图片
private static BufferedImage[] images;
//静态代码块
static {
images = new BufferedImage[5];
for (int i = 0; i < images.length; i++) {
images[i] = img.loadImage("封茗囧茵" + i + ".gif");
}
}
private int speed;//速度
public 封茗囧茵(){
super(49, 36);
this.speed = 5;
}
public void yiDongFangFa(){
this.y += speed;
}
//得到图片
int index = 1;
@Override
public BufferedImage getImageFangFa() {//10M
if (panDuanLife()) {
return images[0];
}else if(panDuanDead()){//图片的切换
BufferedImage img = images[index++];
if (index == images.length) {
lifeOrDeadOrRemove = remove;
}
return img;
}
/*images[index++];
* index = 1;
* 10M images[1] index = 2 返回images[1]
* 20M images[2] index = 3 返回images[2]
* 30M images[3] index = 4 返回images[3]
* 40M images[4] index = 5 返回images[4]
*
*/
return null;
}
@Override
public int getScoreFangFa() {
return 1;
}
}






package duiXiang;
// 下面为得分接口:
public interface diRen {
/*用接口调用得分方法:*/
public int getScoreFangFa();
}


package duiXiang;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import mains.mains;
public abstract class duiXiangFuLeiFangFa {
// 成员变量
protected int width;// 宽
protected int height;// 高
protected int x;// x坐标
protected int y;// y坐标
// 设计三种状态
public static final int life = 0;// 存活
public static final int dead = 1;// over
public static final int remove = 2;// 删除
public int lifeOrDeadOrRemove = life;// 当前状态为存活
public duiXiangFuLeiFangFa(int width, int height) {
this.width = width;
this.height = height;
Random rand = new Random();
this.x = rand.nextInt(mains.quanJvWidth
- this.width);
this.y = -this.height;
}
/** 下面画出对象,背景等的构造方法,构造方法和
* 把它包住的类的名称是相同的 */
public duiXiangFuLeiFangFa(int width, int height,
int x, int y) {
this.width = width;
this.height = height;
this.x = x;
this.y = y;
}
// yiDongFangFa: 移动方法
public void yiDongFangFa() {
}
// 下面是调用图片的抽象方法:
public abstract BufferedImage getImageFangFa();
/** paintObjectDuiXiangFangFa:
* 下面是用来绘制图片到页面的方法:
*
* */
public void paintObjectDuiXiangFangFa(Graphics g) {
g.drawImage(this.getImageFangFa(), this.x, this.y
,null);
}
/** 判断当前状态是不是存活的 */
// lifeOrDeadOrRemove:生或死或移除
public boolean panDuanLife() {
return lifeOrDeadOrRemove == life;
}
/** 判断当前状态是不是over的 */
public boolean panDuanDead() {
return lifeOrDeadOrRemove == dead;
}
/** 判断当前状态是不是删除的 */
public boolean panDuanRemove() {
return lifeOrDeadOrRemove == remove;
}
/** 检测越界的方法 */
public boolean outOfBounds() {
return this.y >= mains.quanJvHeight;
}
public boolean hit(duiXiangFuLeiFangFa other) {
int x1 = this.x - other.width;
int y1 = this.y - other.height;
int x2 = this.x + this.width;
int y2 = this.y + this.height;
int x = other.x;
int y = other.y;
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
public void goDead() {
lifeOrDeadOrRemove = dead;// 将对象状态修改为DAED
}
public int getScoreFangFa() {
// TODO Auto-generated method stub
return 0;
}
}


package duiXiang;
public interface jiangLi {
int getAwardType();
}




package duiXiang;
import java.io.*;
import java.text.Format;
import javax.sound.sampled.*;
public class shengyin implements Runnable{
private String wenjianming;
public shengyin(String w){
this.wenjianming=w;
}
@Override
public void run() {
File f=new File(wenjianming);
AudioInputStream ais=null;
try {
ais=AudioSystem.getAudioInputStream(f);
AudioFormat af=ais.getFormat();
SourceDataLine sdl=null;
DataLine.Info dl=new DataLine.Info(SourceDataLine.class,af);
sdl=(SourceDataLine)AudioSystem.getLine(dl);
sdl.open(af);
sdl.start();
int len=0;
byte[] b=new byte[1024];
while(len!=-1){
len=ais.read(b,0,b.length);
if(len>=0){
sdl.write(b,0,len);
}
}
sdl.drain();
sdl.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}


package duiXiang;
import img.img;
import java.awt.image.BufferedImage;
import java.util.Random;
import mains.mains;
public class Warma extends duiXiangFuLeiFangFa implements jiangLi{
private static BufferedImage[] imageArray;
// 静态代码块
static {
// 这里调用的5张图片只是透明度变得越来越小,
// 当被“击落”时,会一起4张图片调用,会“消失得”更自然
imageArray = new BufferedImage[5];
for (int i = 0; i < imageArray.length; i++) {
imageArray[i] = img.loadImage("Warma" + i + ".gif");
}
// images = new BufferedImage[1];
//
//
// images[0] = img.loadImage("Warma0.gif");
//
}
private int xSpeed;// x坐标的速度
private int ySpeed;// y坐标的速度
private int awardType;// 获取奖励的类型
public Warma() {
super(29, 39);
xSpeed = 1;
ySpeed = 2;
Random rand = new Random();
awardType = rand.nextInt(2);// 0 1
}
public void yiDongFangFa() {
x += xSpeed;
y += ySpeed;
if (x < 0 || x >= mains.quanJvHeight - this.width) {
xSpeed *= -1;
}
}
// 得到图片
int index = 1;
@Override
public BufferedImage getImageFangFa() {// 10M
if (panDuanLife()) {
return imageArray[0];
} else if (panDuanDead()) {// 图片的切换
BufferedImage img = imageArray[index++];
if (index == imageArray.length) {
lifeOrDeadOrRemove = remove;
}
return img;
}
return null;
}
@Override
public int getAwardType() {
return awardType;
}
}
