Java实现坦克⼤战⼩游戏(源码+注释)
通过本项⽬能够更直观地理解应⽤层和运输层⽹络协议, 以及继承封装多态的运⽤. ⽹络部分是本⽂叙述的重点, 你将看到如何使⽤Java建⽴TCP和UDP连接并交换报⽂, 你还将看到如何⾃⼰定义⼀个简单的应⽤层协议来让⾃⼰应⽤进⾏⽹络通信
⼀.主要设计内容:
1、需要有图形⽤户界⾯,让⽤户能看到游戏给出的反馈。
2、不同队伍的坦克,须显⽰不同的外观,以区分敌我。
3、坦克能够开⽕,攻击敌⽅,但不能攻击队友。
4、需要有不可被⼦弹穿透的墙体,以及墙体有可被摧毁和不可被摧毁两种。
5、敌⽅坦克有⽣命值,并⾮被击中⼀次就会爆炸。
6、游戏结束时会有胜利或失败场景
7、游戏结束后可重新开始。
⼆. 程序源码基本结构
三.设计的环境、⽅法及措施:
主要设备:电脑。
软件:eclipse软件。
⽅法措施:
利⽤学到的java基础应⽤程序知识实现需求分析上的功能模块,并在设计与实现时分析遇到的问题并解决,对实现的模块进⾏测试,查不⾜,尽量做到满⾜⽤户要求
四. 实现了哪些功能
此系统是使⽤Java语⾔实现坦克⼤战游戏程序,玩家通过连接访问进⼊游戏,通过操纵坦克来守卫基地,玩家还可以获得超级武器来提升坦克的属性,摧毁全部敌⽅坦克来取得胜利。本系统结构如下:
(1)⾯板功能:
对双⽅坦克、基地、河道、草坪、普通墙与铁墙等地图元素,还实现了页⾯按钮功能,玩家可以点击
按钮来实现相应的功能。
(2)坦克功能:
操作玩家坦克的⽅法,还设置了超级武器,玩家吃掉后会获得特殊技能。
(3)⼦弹功能:
设置了⼦弹打中不同物体对象产⽣的不同效果。
五. 运⾏效果
六. 实现思路
数据存储表⽰: 在JPanel绘制图像,统⼀规定各个⽅块的⼤⼩为同⼀⼤⼩(如墙壁,坦克之类,⼦弹除外),从⽽⽅便使⽤⼆维数组存储地图的各个元素。
关于检测物体碰撞,这⾥使⽤了⼀个MyImage的⽗类,将坦克,墙壁
定义为继承这个⽗类的⼀个类。
int width = Game.width;
int height = Game.height;
简单的java游戏代码//⼆维地图的坐标
Coord coord;
//屏幕上的像素坐标
int x;
int y;
MyImage(Coord coord){
x = coord.x * width;
y = coord.y * height;
}
private Rectangle getRect(){
return new Rectangle(x, y, width, height);
}
//碰撞检测
boolean isIntersects(MyImage other){
Rect().intersects(getRect());
}
}
图像打印则借助遍历两个ConcurrentHashMap分别储存坦克和其他类型的⽅块。将这些⽅块使⽤Map⽽不是使⽤数组是因为管理起来⽐较⽅便,⽽⼆维数组则是为了寻路算法⽽准备的,防⽌了频繁使⽤上⾯的两个Map⽽导致线程锁的问题。
七. 遇到的问题
ava的按键监听在响应按键长按时会有1-2秒的延迟,导致操作⼿感极差
解决⽅法:在坦克类中设置⼀个布尔属性move以及整形变量key储存键⼊的按键值,创建⼀个线程来响应按键。
实现代码:
//按键响应的线程类
class MyTankMove implements Runnable{
public void run(){
while(flag){
GetKey(key);
while(move){//决定是否移动
try {
e.printStackTrace();
Thread.sleep(100);
} catch (InterruptedException e){
e.printStackTrace();
}
try {
Thread.sleep(10);//防⽌⽆按键时陷⼊死循环导致线程堵塞
} catch (InterruptedException e){
}
}
}
按键监听事件,即给key和move赋值
private class KeyBoradListener extends KeyAdapter{
public void keyPressed(KeyEvent e){
super.keyPressed(e);
int key = e.getKeyCode();
if(key<65){//为了实现双⼈对战⽽设置的。。。
if(key!=KeyEvent.VK_SHIFT&&!MyTank.isEmpty()){
}
}
else{
if(key!=KeyEvent.VK_G&&!MyTank.isEmpty()){
switch(key){
case KeyEvent.VK_W:key = KeyEvent.VK_UP;break;
case KeyEvent.VK_A:key = KeyEvent.VK_LEFT;break;
case KeyEvent.VK_S:key = KeyEvent.VK_DOWN;break;
case KeyEvent.VK_D:key = KeyEvent.VK_RIGHT;break;
}
}
}
}
public void keyReleased(KeyEvent e){
super.keyReleased(e);
int key = e.getKeyCode();
if(key<65){
if(!MyTank.isEmpty()){
if(key!=KeyEvent.VK_SHIFT&&key==First().key){//避免了同时按两个以上按键后会卡住
}
else{
}
}
}
else{
switch(key){
case KeyEvent.VK_W:key = KeyEvent.VK_UP;break;
case KeyEvent.VK_A:key = KeyEvent.VK_LEFT;break;
case KeyEvent.VK_S:key = KeyEvent.VK_DOWN;break;
case KeyEvent.VK_D:key = KeyEvent.VK_RIGHT;break;
case KeyEvent.VK_G:key = KeyEvent.VK_SHIFT;break;
}
if(!MyTank.isEmpty()){
if(key!=KeyEvent.VK_SHIFT&&key==Last().key){
}
else{
}
}
}
}
}
项⽬内的图⽚资源如何在项⽬导出后也能使⽤
解决⽅法:假设在项⽬的scr⽂件夹中建⽴img⽂件夹,在项⽬的.classpath中加⼀句(Eclipse),也可以通过设置项⽬的Modules,将图像⽂件夹设置为resources(IDEA),并使⽤当前类的名.Resource("/(⽂件名)")).getImage()获得图像对象。
寻路的实现
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论