java单机版坦克游戏(尚学堂)

2024-01-29 11:18

本文主要是介绍java单机版坦克游戏(尚学堂),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

界面客户端 TankClient.java

package com.rs;import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;import javax.swing.*;public class TankClient extends JFrame{public static final int GAME_WIDTH=800;//常量名字母大写public static final int GAME_HEIGHT=600;Tank myTank=new Tank(50,50,true,Tank.Direction.STOP, this);Wall w1=new Wall(200,200,20,150,this),w2=new Wall(300,100,300,20,this);List<Explode> explodes=new ArrayList<Explode>();List<Missile> missiles=new ArrayList<Missile>();List<Tank> tanks=new ArrayList<Tank>();Image offScreenImage=null;public void paint(Graphics g) {//面向对象方法g.drawString("Missiles-count:"+missiles.size(),10,45);g.drawString("Explodes-count:"+explodes.size(),10,60);g.drawString("Tanks-count:"+tanks.size(),10,75);g.drawString("Tanks-lift:"+myTank.getLife(),10,90);for(int i=0;i<missiles.size();i++){Missile m=missiles.get(i);m.hitTanks(tanks);m.hitTank(myTank);m.hitWall(w1);m.hitWall(w2);m.draw(g);}	for(int j=0;j<explodes.size();j++){Explode e=explodes.get(j);e.draw(g);}for(int k=0;k<tanks.size();k++){Tank t=tanks.get(k);t.collidesWithWall(w1);t.collidesWithWall(w2);t.collidesWithTank(tanks);t.draw(g);}myTank.draw(g);w1.draw(g);w2.draw(g);}public void update(Graphics g) {//双缓冲技术if(offScreenImage==null){offScreenImage=this.createImage(GAME_WIDTH,GAME_HEIGHT);}Graphics goffScreen=offScreenImage.getGraphics();Color c=goffScreen.getColor();//前景重刷goffScreen.setColor(Color.GRAY);goffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT);goffScreen.setColor(c);paint(goffScreen);g.drawImage(offScreenImage,0,0,null);}public void lauchFrame(){for(int i=0; i<10; i++){tanks.add(new Tank(50+40*(i+1),50,false,Tank.Direction.D, this));}this.setTitle("<MyTankWar>");this.setBounds(320,150,GAME_WIDTH,GAME_HEIGHT);		setResizable(false);this.setDefaultCloseOperation(EXIT_ON_CLOSE);setBackground(Color.gray);setVisible(true);this.addKeyListener(new KeyMonitor());new Thread(new TankThread()).start();}private static final long serialVersionUID = 1L;public static void main(String[] args) {TankClient tc=new TankClient();tc.lauchFrame();}private class TankThread implements Runnable{public void run() {while(true){repaint();try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}}}private class KeyMonitor extends KeyAdapter{public void keyReleased(KeyEvent e) {myTank.keyReleased(e);}public void keyPressed(KeyEvent e) {myTank.KeyPressed(e);			}		}
}

坦克类 Tank.java:

package com.rs;import java.awt.*;
import java.awt.event.*;
import java.util.*;public class Tank {public static final int XSPEED = 5;public static final int YSPEED = 5;public static final int WIDTH = 30;public static final int HEIGHT = 30;private int x, y,oldX,oldY;TankClient tc;private BloodBar bb=new BloodBar();private boolean live=true;private boolean good;private static Random random=new Random();//一个就够了,所以设为staticprivate int step = random.nextInt(12)+3;private int life = 100;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;// 炮筒默认方向public Tank(int x, int y, boolean good) {this.x = x;this.y = y;this.oldX=x;this.oldY=y;this.good = good;}public Tank(int x, int y, boolean good, Direction dir, TankClient tc) {this(x, y, good);this.dir=dir;this.tc = tc;}public void draw(Graphics g) {if(!live) {if(!good){tc.tanks.remove(this);}return;}Color c = g.getColor();if (good) {g.setColor(Color.CYAN);} else {g.setColor(Color.blue);}g.fillOval(x, y, WIDTH, HEIGHT);g.setColor(c);if(good) bb.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();}private 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 (x < 0)x = 0;if (y < 25)y = 25;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;if(!good){Direction[] dirs=Direction.values();if(step == 0){step = random.nextInt(12)+3;int rn=random.nextInt(dirs.length);dir=dirs[rn];}	step--;if(random.nextInt(40)>38) this.fire();}		}public void stay(){x=oldX;y=oldY;}public void KeyPressed(KeyEvent e) {// 键盘按下int key = e.getKeyCode();switch (key) {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();}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;}public void keyReleased(KeyEvent e) {// 键盘松开int key = e.getKeyCode();switch (key) {case KeyEvent.VK_F:fire();break;case KeyEvent.VK_A:superFire();break;case KeyEvent.VK_LEFT:bL = false;break;case KeyEvent.VK_UP:bU = false;break;case KeyEvent.VK_RIGHT:bR = false;break;case KeyEvent.VK_DOWN:bD = false;break;}locateDirection();}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, good, ptDir, this.tc);tc.missiles.add(m);return m;}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, good, dir,  this.tc);tc.missiles.add(m);return m;}public Rectangle getRect() {return new Rectangle(x,y,WIDTH,HEIGHT);}public boolean isLive() {return live;}public void setLive(boolean live) {this.live = live;}public boolean isGood() {return good;}public boolean collidesWithWall(Wall w){if(this.live && this.getRect().intersects(w.getRect())){this.stay();return true;}return false;}public boolean collidesWithTank(java.util.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;}private void superFire() {Direction[] dirs=Direction.values();for(int i=0;i<8;i++) {fire(dirs[i]);}}public int getLife() {return life;}public void setLife(int life) {this.life = life;}private class BloodBar {public void draw(Graphics g){Color color=g.getColor();g.setColor(Color.red);g.drawRect(x, y+13, WIDTH, 5);int w=WIDTH*life/100;g.fillRect(x, y+13, w, 5);g.setColor(color);}}}

子弹类 Missile.java:

package com.rs;import java.awt.*;
import java.util.List;public class Missile {//Tank子弹类private static final int XSPEED = 10;private static final int YSPEED = 10;public static final int WIDTH=10;public static final int HEIGHT=10;int x,y;Tank.Direction dir;private boolean live=true;private boolean good;private TankClient tc;public Missile(int x, int y, Tank.Direction dir) {//自动生成构造方法this.x = x;this.y = y;this.dir = dir;}public Missile(int x, int y,boolean good, Tank.Direction dir,TankClient tc) {//自动生成构造方法this(x, y, dir);this.good=good;this.tc=tc;}public void draw(Graphics g){if(!live) {tc.missiles.remove(this);return;}Color c=g.getColor();if(!good){g.setColor(Color.blue);} else{g.setColor(Color.BLACK);}		g.fillOval(x,y,WIDTH,HEIGHT);g.setColor(c);	move();}private void move() {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(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT){//出界live=false;}}public boolean isLive() {return live;}public Rectangle getRect(){//四边形return new Rectangle(x,y,WIDTH,HEIGHT);}public boolean hitTank(Tank t){if(this.live && this.getRect().intersects(t.getRect()) && t.isLive() && this.good != t.isGood()) {if(t.isGood()) {t.setLife(t.getLife()-20);if(t.getLife()<=0) t.setLive(false);} else{t.setLive(false);}this.live=false;Explode e=new Explode(x,y,tc);tc.explodes.add(e);return true;}return false;}public boolean hitTanks(List<Tank> tanks){for(int i=0; i<tanks.size(); i++){if(hitTank(tanks.get(i))){return true;}}return false;}public boolean hitWall(Wall w){if(this.live && this.getRect().intersects(w.getRect())){this.live=false;return true;}return false;}}

爆炸效果 Explode.java:

package com.rs;import java.awt.*;public class Explode {// 爆炸(多幅图重碟在一起)int x, y;private boolean live = true;private TankClient tc;int[] diameter = { 5,  12,  26,  49,  20, 3 };int step = 0;public Explode(int x,int y,TankClient tc){this.x=x;this.y=y;this.tc=tc;}public void draw(Graphics g){if(!live) {tc.explodes.remove(this);return;}if(step == diameter.length){live=false;step=0;return;}Color c=g.getColor();g.setColor(Color.orange);g.fillOval(x, y, diameter[step], diameter[step]);g.setColor(c);step ++;}
}

障碍物 Wall.java:

package com.rs;import java.awt.Graphics;
import java.awt.Rectangle;public class Wall {int x,y,w,h;TankClient tc;public Wall(int x, int y, int w, int h, TankClient tc) {this.x = x;this.y = y;this.w = w;this.h = h;this.tc = tc;}public void draw(Graphics g){g.fillRect(x, y, w, h);}public Rectangle getRect(){return new Rectangle(x,y,w,h);}
}


这篇关于java单机版坦克游戏(尚学堂)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/656731

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定