FC版BattleCity(坦克大战)的Java实现!!!!!(二)

本文介绍了作者在开发坦克大战游戏过程中取得的进展,包括主程序框架的搭建、游戏类的设计及数据操作线程的实现。文章还提到了游戏菜单、地图读取、战场绘制等功能的实现细节,并规划了下一步的工作重点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天的成果 :

完成主程序框架搭建,完成主游戏类的框架搭建,完成数据操作线程的框架。

目前实现了开始选择菜单:1P、2P、编辑地图

选择关口frame,读取map文件,目前map文件的格式为txt格式,26×26的地图,另外有一行是关口的坦克信息。

map后期需要压缩,改变存储格式为二进制,压缩大小,统一用一个map文件来存储,自定义地图的时候关口显示好像是第一关,应该需要一个临时的地图存储数据结构…………这个以后再完善。

进入画出黑色战场,根据敌人坦克数量显示标记,显示游戏玩家的生命,战场中显示当前的level。

计算好了战场的大小和每块地面的大小。

明天:明天把图片做好,把map文件加载并根据map文件显示战场。截战场地面地图,一共是6种吧??老家gif、地面gif,爆炸gif(很多帧),炮弹gif,无敌状态gif,各种坦克gif,宝gif,gameover&pause的gif,应该就这么多了。

如果可能的话把编辑战场地图做完。

声音仍然是个大问题,不知道如何截取,应该是mid的,mid的音频占的空间小,速度快,不过也可以用录音机等录成wav格式。麻烦,这个最后弄。

目前有点不妥的地方:

程序一直在rapaint,对CPU占用有点大,不管是否需要repaint都一直调用,并且repaint是重画了整个画布。

应该可以优化成需要时在repaint,只是repaint需要重画的地方,先把需要repaint的地方clear,然后画上新的图片。然后转移显示指针。

程序结构有点不好…………等着重构吧!先实现了再说!

目前的源码和图片:

MainFrame:

 

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

/**
 * 
@author WS
 * @created at 2006-5-3 21:03:20
 
*/


public class MainFrame extends JFrame implements KeyListener {

    
/* 开始从下网上番的大图片 */
    
private Image startImage;

    
/* 游戏坦克状态1 */
    
private Image tankImage1;

    
/* 游戏坦克状态2 */
    
private Image tankImage2;

    
/* 0-1 */
    
public int tankStatus = 0;

    
/* 无敌状态的白框1 */
    
private Image super1Image;

    
/* 无敌状态的白框2 */
    
private Image super2Image;

    
private Image stageImage;

    
private Image tankLetImage;

    
private Image p1LifeImage;

    
private Image p2LifeImage;

    
private Image flagImage;

    
private Image num[] = new Image[10];

    
private int tankX = 140;

    
private int tankY = 265;

    
/* Frames状态机 0-开始 1-选择 2-幕 3-开始显示level 4-游戏中 5-Win 6-地图编辑 …… */
    
public int frames = 0;

    
public boolean gameRunning = true;

    
public int startY = 466;

    
/* 0-单人游戏 1-双人游戏 3-地图编辑 */
    
public int selectGame = 0;

    
private int p1Life = 2;

    
private int p2Life = 2;

    
/* 1-n */
    
public int level = 1;

    
/* 刷新频率 20毫秒 */
    
private long fresh = 20;

    
public int mask = 0;

    
public int leftTank = 20;

    
public char map[][] = new char[27][26];

    
public MainFrame(String title) {
        
super(title);
        loadImages();
        initFrame();
        Thread engine 
= new OperatorThread(this);
        engine.start();
        
this.addWindowListener(new WindowAdapter() {
            
public void windowClosing(WindowEvent e) {
                System.exit(
0);
            }

        }
);
    }


    
private void initFrame() {
        setSize(
520486);
        setVisible(
true);
        setBackground(Color.BLACK);
        createBufferStrategy(
2);
        addKeyListener(
this);
    }


    
private void loadImages() {
        startImage 
= loadImage("D:/eclipse/workspace/Tank/bin/start.gif");
        tankImage1 
= loadImage("D:/eclipse/workspace/Tank/bin/tank1.gif");
        tankImage2 
= loadImage("D:/eclipse/workspace/Tank/bin/tank2.gif");
        stageImage 
= loadImage("D:/eclipse/workspace/Tank/bin/stage.gif");
        tankLetImage 
= loadImage("D:/eclipse/workspace/Tank/bin/tankLet.gif");
        p1LifeImage 
= loadImage("D:/eclipse/workspace/Tank/bin/1plife.gif");
        p2LifeImage 
= loadImage("D:/eclipse/workspace/Tank/bin/2plife.gif");
        flagImage 
= loadImage("D:/eclipse/workspace/Tank/bin/flag.gif");
        
for (int i = 0; i < 10; i++{
            num[i] 
= loadImage("D:/eclipse/workspace/Tank/bin/" + i + ".gif");
        }

        
if (startImage == null{
            System.out.println(
"Null");
        }

    }


    
private Image loadImage(String fileName) {
        
return new ImageIcon(fileName).getImage();
    }


    
public Graphics2D getDoubleGraphics() {
        BufferStrategy strategy 
= this.getBufferStrategy();
        
return (Graphics2D) strategy.getDrawGraphics();
    }


    
private void update() {
        BufferStrategy strategy 
= this.getBufferStrategy();
        
if (!strategy.contentsLost()) {
            strategy.show();
        }

        Toolkit.getDefaultToolkit().sync();
    }


    
// 0-开始 1-选择 2-开始显示level 3-游戏中 4-Win 5-地图编辑
    public void Start() throws Exception {
        
long startTime;
        
long tmp = 0;
        
while (gameRunning) {
            startTime 
= System.currentTimeMillis();
            repaint();
            tmp 
= System.currentTimeMillis() - startTime;
            
// System.out.println(fresh - tmp);
            Thread.sleep((fresh - tmp) < 0 ? 0 : fresh - tmp);
        }

    }


    
private void drawTank(Graphics2D g2, int direct, int posX, int posY,
            
int tankStatus) throws Exception {
        g2.drawImage(startImage, 
0, startY, null);
        
if (tankStatus == 0{
            g2.drawImage(tankImage1, posX, posY, 
null);
        }
 else {
            g2.drawImage(tankImage2, posX, posY, 
null);
        }

    }


    
private void drawLevelMask(Graphics2D g2) throws Exception {
        g2.setColor(Color.GRAY);
        g2.fillRect(
020532, mask);
        g2.fillRect(
0486 - mask, 532486);
    }


    
private void drawLevel(Graphics2D g2) {
        g2.setColor(Color.GRAY);
        g2.fillRect(
00532486);
        g2.drawImage(stageImage, 
200220null);
        
if (level < 10{
            g2.drawImage(num[level], 
300220null);
        }
 else {
            String tmp 
= level + "";
            g2.drawImage(num[Integer.parseInt(tmp.substring(
01))], 285220,
                    
null);
            g2.drawImage(num[Integer.parseInt(tmp.substring(
12))], 300220,
                    
null);
        }

    }


    
private void play(Graphics2D g2) {
        g2.setColor(Color.GRAY);
        g2.fillRect(
00, (intthis.size().getWidth(), (intthis.size()
                .getHeight());
        g2.setColor(Color.BLACK);
        g2.fillRect(
3050416416);
        
if (mask > 0{
            g2.setColor(Color.GRAY);
            g2.fillRect(
00532, mask);
            g2.fillRect(
0486 - mask, 532486);
        }
 else {
            
int startX = 466;
            
int startY = 70;
            
boolean left = true;
            
for (int i = 0; i < leftTank; i++{
                g2.drawImage(tankLetImage, startX, startY, 
null);
                
if (left) {
                    startX 
+= 16;
                }
 else {
                    startX 
-= 16;
                    startY 
+= 16;
                }

                left 
= !left;
            }

            
// 画出敌人坦克数量,当前level和life
            g2.drawImage(p1LifeImage, 466270null);
            g2.drawImage(num[p1Life], 
482287null);
            
// System.out.println("P1Life");
            if (selectGame == 1{
                g2.drawImage(p2LifeImage, 
466320null);
                g2.drawImage(num[p1Life], 
482337null);
            }

            g2.drawImage(flagImage, 
466380null);
            
if (level < 10{
                g2.drawImage(num[level], 
482412null);
            }
 else {
                String tmp 
= level + "";
                g2.drawImage(num[Integer.parseInt(tmp.substring(
01))], 466,
                        
412null);
                g2.drawImage(num[Integer.parseInt(tmp.substring(
12))], 482,
                        
412null);
            }

        }

        
// 根据map文件画出战场
        
// 左30上20右62下16共512*446 战场:417*406
        
// 1块34*34 13*34=442 442*442
        
// 32*32=416
    }


    
public void paint(Graphics g) {
        
try {
            
switch (frames) {
            
case 0:
                getDoubleGraphics().drawImage(startImage, 
0, startY, null);
                
break;
            
case 1:
                drawTank(getDoubleGraphics(), 
4, tankX, tankY, tankStatus);
                
break;
            
case 2:
                drawLevelMask(getDoubleGraphics());
                
break;
            
case 3:
                drawLevel(getDoubleGraphics());
                
break;
            
case 4:// StartGame
                play(getDoubleGraphics());
                
break;
            
case 5:
                
break;
            
case 6:
                
break;
            }

            update();
        }
 catch (Exception e) {

        }

    }


    
private void mapInit() {
        File mapFile 
= new File("D:/eclipse/workspace/Tank/bin/level.txt");
        BufferedReader br 
= null;
        
try {
            br 
= new BufferedReader(new FileReader(mapFile));
            String tmp 
= null;
            
int i = 0;
            
while ((tmp = br.readLine()) != null{
                tmp.toCharArray();
                map[i
++= tmp.toCharArray();
            }

        }
 catch (FileNotFoundException e) {
        }
 catch (IOException e) {
        }

    }


    
public void keyPressed(KeyEvent e) {
        
// System.out.println("Key:" + e.getKeyCode());
        switch (e.getKeyCode()) {
        
case KeyEvent.VK_G:
            
if (frames == 1{
                selectGame
++;
                
if (selectGame == 3{
                    selectGame 
= 0;
                }

                
if (selectGame == 0{
                    tankY 
= 265;
                }
 else if (selectGame == 1{
                    tankY 
= 297;
                }
 else if (selectGame == 2{
                    tankY 
= 330;
                }

            }

            
break;
        
case KeyEvent.VK_H:
            
if (frames == 1{
                frames 
= 2;// 幕
            }
 else if (frames == 3{
                
// init Map & Course
                mapInit();
                
// PlaySound();Sleep 4sec;
                frames = 4;
            }

            
break;
        
case KeyEvent.VK_U:
            
// 显示LevelFrame
            if (frames == 3{
                
if (level > 1{
                    level
--;
                }

            }

            
break;
        
case KeyEvent.VK_I:
            
if (frames == 3{
                
if (level < 35{
                    level
++;
                }

            }

            
break;
        
case KeyEvent.VK_J:
            
if (frames == 3{
                
if (level > 1{
                    level
--;
                }

            }

            
break;
        
case KeyEvent.VK_K:
            
if (frames == 3{
                
if (level < 35{
                    level
++;
                }

            }

            
break;
        }

    }


    
public void keyReleased(KeyEvent e) {

    }


    
public void keyTyped(KeyEvent e) {

    }

}

OperatorThread.java

 

public class OperatorThread extends Thread {
    
private MainFrame mainFrame = null;

    
public OperatorThread(MainFrame mainFrame) {
        
this.mainFrame = mainFrame;
    }


    
public void run() {
        
try {
            
while (mainFrame.gameRunning) {
                
switch (mainFrame.frames) {
                
case 0:
                    
for (int i = 0; i < 446; i++{
                        mainFrame.startY
--;
                        Thread.sleep(
10);
                    }

                    mainFrame.frames 
= 1;
                    
break;
                
case 1:
                    
while (mainFrame.frames == 1{
                        
if (mainFrame.tankStatus == 0{
                            mainFrame.tankStatus 
= 1;
                        }
 else {
                            mainFrame.tankStatus 
= 0;
                        }

                        Thread.sleep(
100);
                    }

                    
break;
                
case 2:
                    
for (int i = 0; i <= 233; i++{
                        mainFrame.mask 
= i;
                        Thread.sleep(
1);
                    }

                    mainFrame.frames 
= 3;
                    
break;
                
case 4:
                    
if (mainFrame.mask > 0{
                        mainFrame.mask
--;
                        Thread.sleep(
1);
                        
//System.out.println(mainFrame.mask);
                    }
 else {
                        Thread.sleep(
100);
                    }

                    
break;
                
default:
                    Thread.sleep(
100);
                }

            }

        }
 catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值