java小游戏源代码大全_潜艇大战java代码

java小游戏源代码大全_潜艇大战java代码一、简单介绍这是一个功能相对全的JAVA版坦克大战,界面绘制是通过JAVA的图形化用户界面完成的,包括了菜单界面和游戏界面。其中菜单界面可以供玩家选择重新开始游戏、暂停、继续、是否播放背景音乐、帮助等操作;游戏界面绘制了坦克、河流、草地、鹰碉堡等经典坦克场景,玩家在游戏界面操作坦克开始对战。本游戏使用的主要技术有Swing编程、面向对象编程、多线程编程。本…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

目录

一、简单介绍

二、工程目录

三、具体代码

四、运行效果截图

五、总结

六、说明与下载


一、简单介绍

        这是一个功能相对全的Java版坦克大战,界面绘制是通过Java的图形化用户界面swing完成的,包括了菜单界面和游戏界面。其中菜单界面可以供玩家选择重新开始游戏、暂停、继续、是否播放背景音乐、设置游戏难度等操作;游戏界面绘制了坦克、河流、草地、墙壁、鹰碉堡等经典坦克场景,玩家在游戏界面操作自己的坦克开始对战。

         本游戏使用的主要技术有Swing编程、面向对象编程、多线程编程。本想用I/O编程实现保存游戏数据,感觉单机版的没必要就没弄了。

游戏实现的主要功能有:

1、我方坦克默认可以渡河,碰到墙壁不能走,鹰碉堡被击中游戏结束

2、坦克可以上下左右、以及左上左下右上右下八个方向移动,移动时添加音效

3、坦克可以发子弹(可以连发),发射时添加音效

4、击中对方坦克时,坦克消失,显示爆炸效果;子弹击中墙壁时,子弹消失

5、我方坦克吃到血块时,生命值加30(可以自己设定);我方被击中时每次血量减50

6、移动过程中检测碰撞,包括坦克与坦克,坦克与草地、河流、墙壁等

7、声音处理(开始音乐、背景音乐、移动音效、爆炸音效等)

8、菜单处理(重新开始、暂停/继续游戏、是否播放背景音乐、设置游戏难度、帮助等)

9、默认击中一个敌人得100分,达到1500分进入下一关,一共设置了3关

10、生命数,默认两条命,命数用完游戏结束

二、工程目录

 java小游戏源代码大全_潜艇大战java代码

images文件夹存放草、鹰碉堡和河流图片,墙壁是用画笔画的;audio存放所有音效文件;所有java代码都存放在com.chuenhung.tank包下面。

三、具体代码

由于篇幅有限,这里只贴出Tank类源代码。Tank类是公用的,通过good变量来区分我方和敌人坦克。

Tank类源代码:

package com.chuenhung.tank;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;
/**
* 
*@Description 坦克类,包括坦克移动、坦克发射炮弹等
*@author Chuenhung
*@email 1271826574@qq.com
*@date 2017年1月4日
*/
public class Tank {
// 坦克X方向速度,设置游戏难度时可拓展
public static int XSPEED = 5;
// 坦克Y方向速度,设置游戏难度时可拓展
public static int YSPEED = 5;
// 坦克宽度
public static final int WIDTH = 30;
// 坦克高度
public static final int HEIGHT = 30;
// 坦克是否活着
private boolean live = true;
// 坦克的生命值
private int life = 100;
// 持有对TankClient大管家的引用
TankClient tc;
// 判断是否是我方坦克,默认true
private boolean good=true;
// 用于记录坦克原来的坐标,碰到墙、坦克时方便退一步
private int oldX,oldY;
// 绘制坦克的左上角坐标
private int x, y;
// 用于产生随机数
private static Random r = new Random();
// 用于控制敌人随机发出子弹
private int step = r.nextInt(30)+10;
// 判断是否按下方向键
private boolean bL=false, bU=false, bR=false, bD = false;
// 枚举类型定义了坦克的八个方向,和静止时的方向
enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};
// 坦克的方向
private Direction dir = Direction.STOP;
// 炮筒的方向
private Direction ptDir = Direction.D;
// 血条
private BloodBar bar = new BloodBar();
// 剩余生命数
private int remainLives =2;
// 构造方法
public Tank(int x, int y, boolean good) {
this.x = x;
this.y = y;
this.good = good;
}
// 构造方法
public Tank(int x, int y, boolean good, Direction dir,TankClient tc) {
this(x, y, good);
this.tc = tc;
this.oldX=x;
this.oldY=y;
this.dir=dir;
}
/**
* 
* @Description 画出坦克
* @param g
*/
public void draw(Graphics g) {
if(!live) {
if(!good) {
tc.tanks.remove(this);
}
return;
}
Color c = g.getColor();
if(good) g.setColor(Color.RED);
else g.setColor(Color.BLUE);
g.fillOval(x, y, WIDTH, HEIGHT);
g.setColor(c);
//血条
if(good) bar.draw(g); 
switch(ptDir) {
case L:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT/2);
break;
case LU:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y);
break;
case U:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y);
break;
case RU:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y);
break;
case R:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT/2);
break;
case RD:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT);
break;
case D:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y + Tank.HEIGHT);
break;
case LD:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT);
break;
}
move();
}
/*
* 坦克移动
*/
void move() {
this.oldX=x;
this.oldY=y;
switch(dir) {
case L:
x -= XSPEED;
break;
case LU:
x -= XSPEED;
y -= YSPEED;
break;
case U:
y -= YSPEED;
break;
case RU:
x += XSPEED;
y -= YSPEED;
break;
case R:
x += XSPEED;
break;
case RD:
x += XSPEED;
y += YSPEED;
break;
case D:
y += YSPEED;
break;
case LD:
x -= XSPEED;
y += YSPEED;
break;
case STOP:
break;
}
if(this.dir != Direction.STOP) {
this.ptDir = this.dir;
}
if(!good){
Direction[] dirs = Direction.values();
if(step==0){
step=r.nextInt(30)+10;
int rn = r.nextInt(9);
this.dir=dirs[rn];
}
step--;
//敌人发子弹
if(r.nextInt(40)>36){
this.fire();
}
}
if(x < 0) x = 0;
if(y < 55) y = 55;
if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;
}
/**
* 
*@Description 用于撞到墙、坦克时返回上一步
*/
private void stay(){
x=oldX;
y=oldY;
}
/**
* 
*@Description 按下键时监听
* @param e
*/
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_R:
tc.bloods.clear();
tc.grasses.clear();
tc.rivers.clear();
tc.walls.clear();
tc.missiles.clear();
tc.tanks.clear();
tc.explodes.clear();
//关卡、分数重置
tc.score=0;
tc.level=1;
//草地
tc.newGrass();
//河流
tc.newRiver();
//墙
tc.newWall();
//当在区域中没有坦克时,就出来坦克
if (tc.tanks.size() == 0) {
tc.newTank();
}
tc.myTank = new Tank(220, 560, true, Direction.STOP, tc);//设置自己出现的位置
if(!tc.home.isLive()){
tc.home.setLive(true);
}
tc.dispose();
new TankClient().lauchFrame();
break;
case KeyEvent.VK_LEFT :
bL = true;
break;
case KeyEvent.VK_UP :
bU = true;
break;
case KeyEvent.VK_RIGHT :
bR = true;
break;
case KeyEvent.VK_DOWN :
bD = true;
break;
}
locateDirection();
}
/**
* 
*@Description 定位坦克的方向
*/
void locateDirection() {
if(bL && !bU && !bR && !bD) dir = Direction.L;
else if(bL && bU && !bR && !bD) dir = Direction.LU;
else if(!bL && bU && !bR && !bD) dir = Direction.U;
else if(!bL && bU && bR && !bD) dir = Direction.RU;
else if(!bL && !bU && bR && !bD) dir = Direction.R;
else if(!bL && !bU && bR && bD) dir = Direction.RD;
else if(!bL && !bU && !bR && bD) dir = Direction.D;
else if(bL && !bU && !bR && bD) dir = Direction.LD;
else if(!bL && !bU && !bR && !bD) dir = Direction.STOP;
}
/**
* 
* @Description 松开键时监听
* @param e
*/
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_J:
superFire();
break;
case KeyEvent.VK_SPACE:
fire();
//发射炮弹音效
new Audio(2);
break;
case KeyEvent.VK_LEFT :
bL = false;
new Audio(1);
break;
case KeyEvent.VK_UP :
bU = false;
new Audio(1);
break;
case KeyEvent.VK_RIGHT :
bR = false;
new Audio(1);
break;
case KeyEvent.VK_DOWN :
bD = false;
new Audio(1);
break;
}
locateDirection();		
}
/**
* 
* @Description 坦克开火
* @return 炮弹对象
*/
public Missile fire() {
if(!live)return null;
int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
Missile m = new Missile(x, y, ptDir,this.good, this.tc);
tc.missiles.add(m);
return m;
}
/**
* 
* @Description 坦克根据方向开火
* @return 炮弹对象
*/
public Missile fire(Direction dir) {
if(!live)return null;
int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
Missile m = new Missile(x, y, dir,this.good, this.tc);
tc.missiles.add(m);
return m;
}
/**
* 
* @Description 超级炮弹,可以向八个方向开火
*/
public void superFire(){
Direction[] dirs = Direction.values();
for(int i=0;i<8;i++){
fire(dirs[i]);
}
}
/**
* 
* @Description 判断坦克是否撞墙
* @param w 墙对象
* @return 是否撞墙了
*/
public boolean CollidesWithWall(Wall w){
if(this.live&&this.getRect().intersects(w.getRect())){
this.stay();
return true;
}
return false;
}
public boolean CollidesWithWalls(List<Wall> walls){
for(int i=0;i<walls.size();i++){
Wall w = walls.get(i);
if(this.live&&this.getRect().intersects(w.getRect())){
this.stay();
return true;
}
}
return false;
}
/**
* 
* @Description 判断坦克是否相撞
* @param tanks 多辆坦克
* @return 是否和坦克相撞了
*/
public boolean collidesWithTanks(List<Tank> tanks){
for(int i=0;i<tanks.size();i++){
Tank t = tanks.get(i);
if(this!=t){
if(this.live&&t.isLive()&&this.getRect().intersects(t.getRect())){
this.stay();
t.stay();
return true;
}
}
}
return false;
}
/**
* 
* @Description 坦克是否碰到了鹰碉堡
* @param h 鹰碉堡对象
* @return 是否碰到了鹰碉堡
*/
public boolean CollidesWithHome(Home h){
if(this.live&&h.isLive()&&this.getRect().intersects(h.getRect())){
this.stay();
return true;
}
return false;
}
/**
* 
* @Description 坦克是否碰到了河流,主要是地方坦克调用,我方坦克能直接渡河
* @param r 河流对象
* @return 是否碰到了河流
*/
public boolean CollidesWithRiver(River r){
if(this.live&&this.getRect().intersects(r.getRect())){
this.stay();
return true;
}
return false;
}
/**
* 
*@Description 坦克是否碰到了河流,主要是地方坦克调用,我方坦克能直接渡河
* @param rivers 河流集合
* @return 是否碰到了河流
*/
public boolean CollidesWithRivers(List<River> rivers){
for(int i=0;i<rivers.size();i++){
River t = rivers.get(i);
if(this.live&&this.getRect().intersects(t.getRect())){
this.stay();
return true;
}
}
return false;
}
public Rectangle getRect() {
return new Rectangle(x, y, WIDTH, HEIGHT);
}
/**
* 
*@Description 我方坦克的血条,用于显示我方坦克的生命值
*@author xiaoli
*@date2017年1月4日
*/
private class BloodBar{
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.PINK);
g.drawRect(x,y-10,WIDTH,8);
//里面的
g.setColor(Color.PINK);
int w =WIDTH*life/100;
g.fillRect(x, y-10, w, 8);
g.setColor(c);
}
}
/**
* 
*@Description 吃血块,主要是我方坦克调用
* @param b 血块对象
* @return 是否吃到了血块
*/
public boolean eat(Blood b){
if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect())){
this.life= life + 30;
b.setLive(false);
tc.bloods.remove(b);
//吃血块音效
new Audio(4);
return true;
}
return false;
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
public boolean isGood() {
return good;
}
public int getRemainLives() {
return remainLives;
}
public void setRemainLives(int remainLives) {
this.remainLives = remainLives;
}
}

四、运行效果截图

重新开始、暂停、继续、发射子弹、爆炸效果演示:

java小游戏源代码大全_潜艇大战java代码

渡河、吃血块功能演示:

java小游戏源代码大全_潜艇大战java代码

 

五、总结

源代码参考了马老师的Java坦克大战视频教程以及众多互联网资源,这次练手有利于深入理解Java面向对象编程、Swing界面编程以及多线程编程

大部分功能是本人在实训期间完成(2016.12.30),当时有兴趣想巩固一下Java知识就开始做了
这个坦克大战到这里就告一个段落,时间荏苒,马上就要毕业了,要学的东西很多的,希望以后能够做出更加优秀的作品。
该程序谨供参考,不得用于商业用途,希望大神能提出更多优化的建议,一起交流。
若有关内容侵犯了您的权益请及时联系作者删除,作者邮箱1271826574@qq.com

更新于2021/06/04

六、说明与下载

下载地址

备用下载地址

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186455.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 信贷风控模型搭建及核心风控模式分类

    信贷风控模型搭建及核心风控模式分类一、当前风控模式现状近年来,信用风险管理发展呈现出数据化、模型化、系统化、自动化和智能化的特点。传统的人工专家经验正逐步被模型与算法替代。因此,科技较为领先的金融服务公司会选择采用模型方式完成对借款人的自动评估与审批。目前,对于信贷审核来说主要基于的风控模式为IPC、信贷工厂、大数据三种,每一种都有自己不同的侧重点。二、最核心的风控模式分类1.IPC模式IPC模式起源于德国邮储银行,该模…

  • java spel_SPEL表达式注入-入门篇

    java spel_SPEL表达式注入-入门篇SpringExpressionLanguage(简称SpEL)是一种强大的表达式语言,支持在运行时查询和操作对象图。语言语法类似于UnifiedEL,但提供了额外的功能,特别是方法调用和基本的字符串模板功能。同时因为SpEL是以API接口的形式创建的,所以允许将其集成到其他应用程序和框架中。个人理解就是Spring框架中的一种语言表达式,类似于Struts2中的OGNL的东西。一个最基础的…

  • java finalize逃脱_java finalize方法详解[通俗易懂]

    java finalize逃脱_java finalize方法详解[通俗易懂]1.finalize的作用finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。finalize()与C++中的析构函数不是对应的。C++中的析构函数调用的时机是确定的(对象离开作用域或delete掉),但Java中的finalize的调用具有不确定性不建议用finalize方法完成“非内存资源”的清理工作,但建议用于:①…

  • checking for ZTS… configure: error: pthreads requires ZTS, please re-compile PHP with ZTS enabled

    checking for ZTS… configure: error: pthreads requires ZTS, please re-compile PHP with ZTS enabled

  • 两个向量内积的几何意义_向量外积的几何意义

    两个向量内积的几何意义_向量外积的几何意义https://www.zhihu.com/question/48308610/answer/996133623不过的确,我们要这个东西有什么意义呢?为什么平白无故引入这个概念呢?数学家很多时候引入一个新概念,都是为了方便更其他计算,或解释物理现象。解释物理现象:力的做功,当力的向量和移动距离向量有夹角时,力的功就是力向量与距离向量的点积。方便复杂计算:例如,向量的点积为零,意味着垂直,这在证明垂直问题上有很大作用。…

  • 【Redis】Redis配置文件详解

    【Redis】Redis配置文件详解一、存放位置linux下一定要养成备份配置文件的习惯。我是将配置文件拷贝至/myredis目录下进行操作的;二、Units单位这个在配置文件开始位置1.配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit;2.对大小写不敏感。三、INCLUDES1.和Struts2配置文件类似,可以通过includes包含,redis.c…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号