精华内容
下载资源
问答
  • Java实现经典坦克大战及源代码下载

    万次阅读 多人点赞 2017-01-08 11:22:45
    三、具体代码 由于篇幅有限,这里只贴出Tank类源代码。Tank类是公用的,通过good变量来区分我方和敌人坦克。 Tank类源代码: package com.chuenhung.tank; import java.awt.Color; import java.awt.Graphics; ...

    目录

    一、简单介绍

    二、工程目录

    三、具体代码

    四、运行效果截图

    五、总结

    六、说明与下载


    一、简单介绍

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

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

    游戏实现的主要功能有:

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

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

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

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

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

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

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

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

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

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

    二、工程目录

     

    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面向对象编程、Swing界面编程以及多线程编程

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

    更新于2021/06/04

    六、说明与下载

    下载地址

    展开全文
  • 程序员要学会读源代码

    万次阅读 多人点赞 2014-01-25 19:44:57
    我们必须阅读别人的代码,因为我们只有理解了那些代码之后才能把我们自己的事情做好。请你不要害怕阅读源代码——不管它看起来有多么可怕,也不管它会把你带向何方,跟它去吧!

    原文作者:Jeff Atwood

    在“沟通”这个复杂的领域里,写出能让人类领会并理解的连贯段落比敲出几行让解释器或编译器不致于“呕吐”的软件代码要难得多。

    这就是为什么——就软件开发而言——所有的文档大概都是很差劲的。而且,由于为人写作比为机器写作要困难得多,文档恐怕在可预见的将来还会继续差劲下去。对此,你基本上是无能为力的。

    除了做一件事……


    “卢克,学着去读源代码。”

    译者注:卢克(Luke Skywalker)是电影《星球大战》中的一个角色,他来自塔图因星球,在发现了莉雅公主输入到机器人R2-D2中的求救信息后,他与绝地骑士欧比旺一起迎战邪恶的银河帝国,最终救出了公主。《星球大战》系列电影是由卢卡斯电影公司出品的科幻电影。卢卡斯电影公司首先于1977年推出了《星球大战》,之后又分别于1980年和1983年推出了《星球大战2》和《星球大战3》。之后又分别于1999年、2002年和2005年推出了3部《星球大战前传》系列。

    JavaScript“始终带有源代码”是一股革命性的力量,这也是我提出“阿特伍德法则”的一个主要原因(我对这个法则至今仍然坚信不疑)。即使“查看源代码”(View Source)这个功能没有内嵌(但它完全应该有),你也应该要求查阅在你的软件之下的基础源代码的权限。不管文档上面怎么说,源代码才是最终的事实,是你所能找到的最好的、最确定的、最新的“文档”。这个事实永远不会改变,所以你越早接受这个事实,你作为一名软件开发者的境况就会越好。

    译者注:“阿特伍德定律”(Atwood’s Law)是作者自己提出的一个观点,内容是:任何可以用JavaScript来写的应用,最终都将用JavaScript来写。

    我本来想针对这个问题好好地写一写,但是后来在Hacker News网站上发现Brandon Bloom已经写了一个很棒的帖子。我自愧不如。大家去认真读一下吧,因为他解释了阅读源代码的好处,以及在何种情况下你需要阅读源代码。

    我大约在15岁的时候就开始在微软的平台上工作了,并且以此为业。我曾经作为一名软件开发员为微软在Visual Studio上面做集成工作。从我写下第一行Visual Basic代码后的十多年以来,我希望我可以再也不用和一个封闭的库去链接了。

    使用软件和开发软件是不一样的。当你使用大多数软件的基本功能时,一般不会出现什么问题,因为这条“老”路已经被人走过了很多遍。也许其他一些人碰到了问题,并且有足够多的人把这些问题反映出来,这样会促使核心开发人员修正这些问题。而当你在开发软件的时候,你是在做一些“新”东西。而且,把东西做出来可以有很多条“路”,你会碰到之前从来没有接触过的部分、到达早已腐蚀的角落、走到那些尚未完成的试验性质的代码路径。你会遇到一些边缘情况,它们的问题是已知的,但从来没有被真正地解决过(之前只是被绕开了)。

    有些时候,文档是不完整的。有些时候,它干脆就是错误的。源代码是从来不会撒谎的。对于一名有经验的程序员来说,阅读源代码通常会更快些(尤其在你已经熟悉了软件包架构的情况下)……我现在和几个创业公司在一个中等规模的共享办公区域里一起工作。很多其他公司的首席技术官和工程师都时常跑到我们团队来寻求指导和建议。当他们带着有问题的软件过来的时候,我问他们的第一个问题就是:“嘿,你看过源代码了吗?”

    我鼓励开发人员“git clone”他们依赖的所有源代码。起初,他们都有些害怕。“那个项目太大了。我永远也无法把问题找出来!”“我没那么聪明,看不懂那些代码。”“那些代码太难看了!简直惨不忍睹!”但是,你不必把那些代码翻个底朝天,而只需要跟着线索走。况且,如果你不能理解你所依赖的平台,你又怎么能驾驭你自己的软件呢?在大多数情况下,菜鸟程序员认为漂亮的,往往止于肤浅;而他们认为丑陋的,往往是骇客大师们所写的久经考验的产品级代码。现在,在经过了一两年之后,有几个开发人员专程过来找我,感谢我当初强迫他们在别人的代码里“潜水”或者“畅游”。他们现在的技能都比以前大有长进,而且他们还感叹:真不知道过去在没有别人源代码的时候是怎么把事情做好的……

    译者注:git是一个在开源社区里广泛应用的源代码管理工具。git clone是一条命令,能把远程的源代码复制到本机。

    当你运营一个公司的时候,如果你的软件出了故障,你的客户不会在乎是你的失误还是Linus的,或者是由Rails的开发人员造成的。他们只知道是你的软件出了问题。所有其他人的软件都成了你的软件,因为他们的错误都算到了你的头上。一旦有故障发生,你需要找出问题,并且把它修好。你需要在“应用链”的合适位置把它修复,以减少风险、维护成本以及周转时间。有时候,一个快速的权变措施是最好的;而在其他时候,你得重新编译你的代码。很多时候,你可以让其他人在上游把问题修复了;但是也有很多时候,你得自己动手解决。

    译者注:Linus Torvalds(李纳斯·托瓦兹),是Linux核心的创作者,人称“Linux之父”。美国《时代》周刊对他的评价极高:“有些人生来就具有统率百万人的领袖风范;另一些人则是为写出颠覆世界的软件而生。唯一一个能同时做到这两者的人,就是托瓦兹。”甚至,在《时代》周刊根据读者投票评选出的20世纪100位最重要的人物中,李纳斯居然排到了第15位,而比尔·盖茨不过才是第17位。

    译者注:Rails即指Ruby on rails,是一个构建在Ruby语言之上的Web应用程序框架。

    • 处理封闭软件的问题有两个选择:乞求他们的慷慨救援,或者采用变通方案。
    • 对于开源软件,如果他们的开发者不给力,建议像处理封闭软件的问题那样处理。
    • 老到一些的软件商家倾向于慢慢培养他们维护分支、补丁以及处理其他琐碎事务的能力。

    真正的骇客世界里只有一个简单的事实:如果一个软件在我的机器上运行,那它就是我的软件。我对它负责。我必须把它弄明白。从源代码开始构建是一条必须遵循的原则,而且从不例外。我必须控制我的环境,我还要控制所有我依赖的东西。

    没有人是为了好玩才去读别人的代码的。见鬼了,我甚至都不愿意读我自己的代码。想着你舒服地坐在皮椅上,穿着便装,端上一杯白兰地,阅读着别人的代码来度过一个美妙的夜晚——这个念头真是荒诞至极!

    但是,我们需要能接触到源代码。我们必须阅读别人的代码,因为我们只有理解了那些代码之后才能把我们自己的事情做好。所以,卢克,请你不要害怕阅读源代码——不管它看起来有多么可怕,也不管它会把你带向何方,跟它去吧!

    展开全文
  • 使用word软件 点击插入->对象-文件中的文字->然后浏览任意后缀名文件选择大量文件夹或者文件选择导入即可。

    使用word软件 点击插入->对象-文件中的文字->然后浏览任意后缀名文件选择大量文件夹或者文件选择导入即可。

    展开全文
  • 如何加密/乱C源代码

    万次阅读 热门讨论 2009-05-30 15:23:00
    原文: ... —— 酷壳 ...也向大家展示了一下程序是可以写得让人看不懂的,在那篇文章中,可以看到很多人的留言,很多人都觉得很好玩,是的,那本来是...每一个程序员都有把源代码弄复杂的潜质 ”,大家好自为之。

     

    原文:http://cocre.com/?p=933 —— 酷壳

     

    之前发表了《6个变态的C语言Hello World程序》[酷壳链接] [CSDN链接],主要是是像大家展示了一些C语言的变态玩法。也向大家展示了一下程序是可以写得让人看不懂的,在那篇文章中,可以看到很多人的留言,很多人都觉得很好玩,是的,那本来是用来供朋友们“消遣作乐”,供娱乐娱东而已,不必太过认真。

     

    不过,通过这种极端的写法,大家可以看到源代码都可以写得那么复杂难懂的。大家也许在赞叹之余一笑了之,而我则希望,大家能够在娱乐以后认真思考一下,你不要以为咱们自己不会把代码搞得那么复杂,只不过没有像那6个Hello World一样那么极端,不过,说句老实话,咱们每个程序都有把清晰的程序搞得一团混乱的潜能,只不过程度不一样罢了,我并不是在这里危言耸听,大家好自为之

     

    下面是一个Step by Step的教程,教你如何把一个清晰的代码变得复杂难懂的。当然,这只是一个“简明教程”了。还是那句话——“本文仅供朋友们“消遣作乐”,如果你要觉得有意思的话,顶个贴。如果你觉得没什么意思的话,一笑了之。仅供娱乐而已,不必太过认真。

    正常程序

    下面是一个找出素数的程序:

    void primes(int cap)
    {
        int i, j, composite;
    
        for(i = 2; i < cap; ++i) {
            composite = 0;
            for(j = 2; j * j < i; ++j) {
                composite += !(i % j);
            }
            if(!composite){
                printf("%d/t", i);
            }
        }
    }
    
    int main()
    {
        primes(100);
    }
    

    下面我们来看看如何把上面这段代码搞得复杂难懂。

    第一步、把for变成while

    通常来说,for循坏要以while循坏简单一些,上面的程序有二重for循环,我们不但要把其变成while循环,而且还要把二重循环的变成一重的循环,然后使用大量的if-else语句来判断。

    void primes(int cap) 
    { 
        int i, j, composite, t = 0;
        
        while(t < cap * cap) {
            i = t / cap;
            j = t++ % cap;
            if(i <= 1);
            else if(!j)
                composite = j;
            else if(j == i && !composite)
                printf("%d/t",i);
            else if(j > 1 && j < i)
                composite += !(i % j);  
        }
    }
    
    int main() 
    {
        primes(100);
    }
    

    第二步,把循坏变成递归

    递归在某些时候是可以把代码变得简单,但大多数的情况下是把代码变得复杂,而且很没有效率。下面是把上面的while循环变成了递归。变成了递归后,函数的参数都变成3个了。

    void primes(int cap, int t, int composite) 
    {
        int i,j;
        i = t / cap;
        j = t % cap;
        if(i <= 1)
            primes(cap,t+1,composite);
        else if(!j)
            primes(cap,t+1,j);
        else if(j == i && !composite)
            (printf("%d/t",i), primes(cap,t+1,composite));
        else if(j > 1 && j < i)
            primes(cap,t+1, composite + !(i % j));
        else if(t < cap * cap)
            primes(cap,t+1,composite);
    }
     
    int main() 
    {
        primes(100,0,0);
    }
    

    第三步,弄乱代码结构/使用没有含义的变量名

    关于如何弄乱代码结构,其中一个小技巧是,使用“?”表达式代替if-else语句。

    void primes(int m, int t, int c) 
    {
        int i,j;
        i = t / m;
        j = t % m;
        (i <= 1) ? primes(m,t+1,c) : (!j) ? primes(m,t+1,j) : (j == i && !c) ? 
        (printf("%d/t",i), primes(m,t+1,c)) : (j > 1 && j < i) ? 
        primes(m,t+1,c + !(i % j)) : (t < m * m) ? primes(m,t+1,c) : 0;
    }
     
    int main() 
    {
        primes(100,0,0);
    }
    

    第四步,取消临时变量

    临时变量一般用来保存反复使用的一个表达式的值。使用大量重复的表达式来取消这些临时变量的也可以让代码复杂起来。

    void primes(int m, int t, int c) 
    {
      ((t / m) <= 1) ? primes(m,t+1,c) : !(t % m) ? primes(m,t+1, t % m) : 
      ((t % m)==(t / m) && !c) ? (printf("%d/t",(t / m)), primes(m,t+1,c)) : 
      ((t % m)> 1 && (t % m) < (t / m)) ? primes(m,t+1,c + !((t / m) % (t % m))) : 
      (t < m * m) ? primes(m,t+1,c) : 0;
    }
    
     
    int main() 
    {
        primes(100,0,0);
    }
    

    第五步,继续弄乱变量名

    我们知道,下划线是合法的变量名,所以,我们不妨用__,___,____来代替m,t,c。函数名也可以使用下划线来代替。让我们来看看求素数的函数能变成什么。

    void _(int __, int ___, int ____) 
    {
        ((___ / __) <= 1) ? _(__,___+1,____) : !(___ % __) ? _(__,___+1,___ % __) : 
        ((___ % __)==(___ / __) && !____) ? (printf("%d/t",(___ / __)), 
        _(__,___+1,____)) : ((___ % __) > 1 && (___ % __) < (___ / __)) ? 
        _(__,___+1,____ + !((___ / __) % (___ % __))) : (___ < __ * __) ? 
        _(__,___+1,____) : 0;
    } 
    
    int main() 
    {
        _(100,0,0);
    }
    

    第六步,移除常量

    在上面的程序中,还有一些常量,你可以通过增加一个宏定义,或是增加一个函数的形参来取代这一常量。

    void _(int __, int ___, int ____, int _____) 
    {
        ((___ / __) <= _____) ? _(__,___+_____,____,_____) : !(___ % __) ? _(__,___+_____,___ % __, _____) : 
        ((___ % __)==(___ / __) && !____) ? (printf("%d/t",(___ / __)), 
        _(__,___+_____,____,_____)) : ((___ % __) > _____ && (___ % __) < (___ / __)) ? 
        _(__,___+_____,____,_____ + !((___ / __) % (___ % __))) : (___ < __ * __) ? 
        _(__,___+_____,____,_____) : 0;
    } 
     
    int main() {
        _(100,0,0,1); 
    }
    

    程序到这里应该差不多了。还是那句话——“每一个程序员都有把源代码弄复杂的潜质”,大家好自为之。

    展开全文
  • linux源代码

    千次阅读 2012-07-25 11:22:10
    在Internet,有人制作了源代码导航器,为阅读源代码提供了良好的条件,站点为lxr.linux.no/source。 下面给出阅读源代码的线索: 系统的启动和初始化: 在基于Intel的系统上,当loadlin.exe或LILO
  • Jinja2 源代码分析

    千次阅读 2015-04-24 22:36:57
    介绍了 Jinja 2.0 的源代码结构,以及 Jinja 2.0 要解决的核心问题,并举例说明了如何将 HTML 模板转化为 Python 代码的过程。
  • kali源代码简单说明

    千次阅读 2017-09-22 10:34:10
    kaldi源代码简单说明 kaldi是开源的,基于C++的语音识别工具。一方面语音识别有较高的技术门槛,包含了很多方面的东西,另一方面kaldi集成了太多的东西,造成了其代码量很大,阅读起来很困难。 kaldi现在集成了很...
  • wsgiref 源代码分析

    千次阅读 热门讨论 2014-01-27 18:20:43
    介绍了Python Web 开发标准 WSGI 的官方参考实现 wsgiref 的源代码,对源代码结构,层次关系,最重要代码进行了介绍。
  • 如何看懂源代码--(分析源代码方法)

    千次阅读 2012-02-18 13:43:42
    如何看懂源代码--(分析源代码方法)   我们在写程序时,有不少时间都是在看别人的代码。 例如看小组的代码,看小组整合的守则,若一开始没规划怎么看, 就会“噜看噜苦(台语) ” 不管是参考也好,从开源...
  • FFplay源代码分析:整体流程图

    万次阅读 多人点赞 2013-09-24 16:22:40
    FFplay源代码的流程图如图所示,网上的,不记得从哪的了,但是流程很清晰。看完FFplay源代码之后再看这个图感觉整个代码结构一目了然。
  • 苹果Objective-C源代码

    千次阅读 2019-06-02 11:28:27
    GitHub地址: ... 苹果Objective-C源代码,里面分不同版本。我把源码从苹果官方网站上下载并提交到github上的,因为苹果官方网站访问实在太慢了。 官方源码在线查看地址 官方源码下载地址 ...
  • 从 https://android.googlesource.com/ 上弄源代码下来真是不容易,不但得用 vpn,repo 还得半天。github 的速度就快多了,关键是不用 vpn,随时可以下载。而且 github 还可以直接下载 zip 包,那速度可不是 repo ...
  • 用ILspy反编译了一个dll文件,出现语法错误(下面红色代码),代码类型CS0571。请大神指教,该怎么改 public static string GetNewId(Socket sktX, string sTbName, string sKeyFld, int nLength, string sHeader, ...
  • 源代码管理十诫

    千次阅读 2014-10-24 13:47:36
    若是还有可以毫无偏见地涉及各个编程语言,比源代码管理软件更必要的工具,我倒是很想见识一下。源代码管理软件是我们工作的必备工具,是许多开发团队的血液。那为什么我们都会对它有所误解呢?为什么都很难理解版本...
  • SpringMVC项目源代码加密

    千次阅读 热门讨论 2018-03-24 20:08:38
    前段时间有个项目快做完时老板要求上线的时候项目代码必须加密(我们的项目是Java开发的Web项目,用的SpringMVC框架),当时考虑最简单的方法就是壳加密,因为之前在其他项目中用过SafeNet的Hasp加密锁,所以考虑...
  • 最近进行Andorid性能优化的前期调研,后面要修改Andorid源代码插一些桩,提前把编译环境搞起来。官方推荐使用ubuntu,公司网络限制等等不好,所以尝试在Windows开发机上使用docker,虚拟化ubuntu出来进行编译。...
  • 最近看源代码,很痛苦
  • 若是还有可以毫无偏见地涉及各个编程语言,比源代码管理软件更必要的工具,我倒是很想见识一下。源代码管理软件是我们工作的必备工具,是许多开发团队的血液。那为什么我们都会对它有所误解呢?为什么都很难理解版本...
  • 如何阅读一份源代码

    千次阅读 多人点赞 2021-04-09 11:31:18
    阅读源代码的能力算是程序员的一种底层基础能力之一,这个能力之所以重要,原因在于: 不可避免的需要阅读或者接手他人的项目。比如调研一个开源项目,比如接手一个其他人的项目。 阅读优秀的项目源码是学习他人...
  • Java 学生选课系统 源代码

    千次阅读 多人点赞 2020-11-03 15:39:06
    源代码 由于代码量较大,所有代码以百度网盘链接形式给出(永久有效)。 百度网盘链接 提取码:0713 解压后里面的内容应该是这样的: 它包含了所有部分的代码。这里我使用eclipse编程,他们的组织形式是: 按照这...
  • 如何生成源代码

    2020-06-13 17:48:24
    在本文中,我将讨论可以通过编程方式生成源代码的软件开发的不同阶段,并将比较不同的方法。 我还将描述在特定阶段生成代码的特定工具的体系结构和想法(尤里卡时刻的种类)。 手动地 这是标题中设置的问题的答案...
  • 1 将dedecms默认的编辑...将这句代码改成如下的代码: allowFileManager : {$allowFileManager}, afterBlur: function(){this.sync();}  还有疑问 QQ:754042832 www.029dm.net
  • myeclipse查看java源代码的设置方法

    千次阅读 2014-11-01 15:26:23
    搞java开发的,如果不看源代码
  • QT5贪吃蛇 简单源代码

    千次阅读 2019-01-04 16:20:37
    下载地址https://download.csdn.net/download/wenzhibincom/10895755 目前只做了撞墙判断和开始暂停功能,吃尾巴判定下次在了.参考了Qt学习之路里面的源代码.
  • autocad形源代码 许多开发人员和地理信息系统(GIS)专业人员无法使用图形交换格式(DXF)或“图形”(DWG)文件。 这些AutoCAD格式通常要求您具有Windows®和AutoCAD副本才能打开它们。 使用一些方便的开源库,您...
  • BASE64Encode编码,jar包(源代码打包)

    千次下载 热门讨论 2013-10-25 16:45:53
    BASE64Encode 编码,在andorid没有这个编码,这里面有打成jar包,可以导进去。用源代码打包的。手懒不愿意自己得话,可以下载导进去。里面附带着源代码,也可将源代码开进去直接使用,希望能帮助大家。
  • maven如何实现创建带源代码的jar包

    千次阅读 2016-08-15 17:11:18
    实现目标maven打包,在生成的jar包中带有源代码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 93,274
精华内容 37,309
关键字:

怎么弄源代码