Compare commits

..

5 Commits
master ... dp

@ -33,16 +33,6 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.76.Final</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -57,11 +57,11 @@ public class Audio {
public void play() { public void play() {
try { try {
byte[] b = new byte[1024*5]; byte[] b = new byte[1024 * 5];
int len = 0; int len = 0;
sourceDataLine.open(audioFormat, 1024*5); sourceDataLine.open(audioFormat, 1024 * 5);
sourceDataLine.start(); sourceDataLine.start();
//System.out.println(audioInputStream.markSupported()); // System.out.println(audioInputStream.markSupported());
audioInputStream.mark(12358946); audioInputStream.mark(12358946);
while ((len = audioInputStream.read(b)) > 0) { while ((len = audioInputStream.read(b)) > 0) {
sourceDataLine.write(b, 0, len); sourceDataLine.write(b, 0, len);

@ -1,66 +1,26 @@
package com.example.tankbattle; package com.example.tankbattle;
import com.example.tankbattle.net.Client; import com.example.tankbattle.abstractfactory.BaseBullet;
import com.example.tankbattle.net.TankDieMessage; import com.example.tankbattle.abstractfactory.BaseTank;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.UUID;
public class Bullet { public class Bullet extends BaseBullet {
private static final int SPEED = 6; private static final int SPEED = 6;
public static int WIDTH = ResourceMgr.bulletD.getWidth(); public static int WIDTH = ResourceMgr.bulletD.getWidth();
public static int HEIGHT = ResourceMgr.bulletD.getHeight(); public static int HEIGHT = ResourceMgr.bulletD.getHeight();
private Rectangle rect = new Rectangle(); Rectangle rect = new Rectangle();
private UUID id = UUID.randomUUID();
private UUID playerId;
public UUID getPlayerId() {
return playerId;
}
public void setPlayerId(UUID playerId) {
this.playerId = playerId;
}
private int x, y; private int x, y;
private Dir dir; private Dir dir;
private boolean living = true; private boolean living = true;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Dir getDir() {
return dir;
}
public void setDir(Dir dir) {
this.dir = dir;
}
TankFrame tf = null; TankFrame tf = null;
private Group group = Group.BAD; private Group group = Group.BAD;
public Bullet(UUID playerId,int x, int y, Dir dir, Group group, TankFrame tf) { public Bullet(int x, int y, Dir dir, Group group, TankFrame tf) {
this.playerId = playerId;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.dir = dir; this.dir = dir;
@ -71,6 +31,8 @@ public class Bullet {
rect.y = this.y; rect.y = this.y;
rect.width = WIDTH; rect.width = WIDTH;
rect.height = HEIGHT; rect.height = HEIGHT;
tf.bullets.add(this);
} }
public Group getGroup() { public Group getGroup() {
@ -81,6 +43,7 @@ public class Bullet {
this.group = group; this.group = group;
} }
@Override
public void paint(Graphics g) { public void paint(Graphics g) {
if (!living) { if (!living) {
tf.bullets.remove(this); tf.bullets.remove(this);
@ -130,34 +93,19 @@ public class Bullet {
if (x < 0 || y < 0 || x > TankFrame.GAME_WIDTH || y > TankFrame.GAME_HEIGHT) living = false; if (x < 0 || y < 0 || x > TankFrame.GAME_WIDTH || y > TankFrame.GAME_HEIGHT) living = false;
} }
public UUID getId() { @Override
return id; public void collideWith(BaseTank tank) {
} if (this.group == tank.getGroup()) return;
if (this.rect.intersects(tank.rect)) {
public void setId(UUID id) {
this.id = id;
}
public void collideWith(Tank tank){
if (this.playerId.equals(tank.getId())) {
return;
}
if (this.living && tank.isLiving() && this.rect.intersects(tank.rect)) {
tank.die(); tank.die();
this.die(); this.die();
Client.INSTANCE.send(new TankDieMessage(this.id, tank.getId())); int eX = tank.getX() + Tank.WIDTH / 2 - Explode.WIDTH / 2;
int eY = tank.getY() + Tank.HEIGHT / 2 - Explode.HEIGHT / 2;
tf.explodes.add(new Explode(eX, eY, tf));
} }
} }
public void die() { private void die() {
this.living = false; this.living = false;
} }
public boolean isLiving() {
return living;
}
public void setLiving(boolean living) {
this.living = living;
}
} }

@ -0,0 +1,14 @@
package com.example.tankbattle;
public class DefaultFireStrategy implements FireStrategy {
@Override
public void fire(Tank t) {
int bX = t.x + Tank.WIDTH/2 - Bullet.WIDTH/2;
int bY = t.y + Tank.HEIGHT/2 - Bullet.HEIGHT/2;
new Bullet(bX, bY, t.dir, t.group, t.tf);
if(t.group == Group.GOOD) new Thread(()->new Audio("audio/tank_fire.wav").play()).start();
}
}

@ -1,29 +1,34 @@
package com.example.tankbattle; package com.example.tankbattle;
import com.example.tankbattle.abstractfactory.BaseExplode;
import java.awt.Graphics; import java.awt.Graphics;
public class Explode { public class Explode extends BaseExplode {
public static int WIDTH = ResourceMgr.explodes[0].getWidth(); public static int WIDTH = ResourceMgr.explodes[0].getWidth();
public static int HEIGHT = ResourceMgr.explodes[0].getHeight(); public static int HEIGHT = ResourceMgr.explodes[0].getHeight();
private int x, y; private int x, y;
TankFrame tf = null;
private int step = 0; private int step = 0;
public Explode(int x, int y) { public Explode(int x, int y, TankFrame tf) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.tf = tf;
new Thread(()->new Audio("audio/explode.wav").play()).start(); new Thread(()->new Audio("audio/explode.wav").play()).start();
} }
@Override
public void paint(Graphics g) { public void paint(Graphics g) {
g.drawImage(ResourceMgr.explodes[step++], x, y, null); g.drawImage(ResourceMgr.explodes[step++], x, y, null);
if (step >= ResourceMgr.explodes.length) { if (step >= ResourceMgr.explodes.length)
TankFrame.INSTANCE.explodes.remove(this); tf.explodes.remove(this);
}
} }
} }

@ -0,0 +1,5 @@
package com.example.tankbattle;
public interface FireStrategy {
void fire(Tank Tank);
}

@ -0,0 +1,17 @@
package com.example.tankbattle;
public class FourDirFireStrategy implements FireStrategy {
@Override
public void fire(Tank t) {
int bX = t.x + Tank.WIDTH/2 - Bullet.WIDTH/2;
int bY = t.y + Tank.HEIGHT/2 - Bullet.HEIGHT/2;
Dir[] dirs = Dir.values();
for(Dir dir : dirs) {
t.tf.gf.createBullet(bX, bY, dir, t.group, t.tf);
}
if(t.group == Group.GOOD) new Thread(()->new Audio("audio/tank_fire.wav").play()).start();
}
}

@ -1,31 +1,21 @@
package com.example.tankbattle; package com.example.tankbattle;
import com.example.tankbattle.net.Client;
public class Main { public class Main {
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
TankFrame tf = TankFrame.INSTANCE; TankFrame tf = new TankFrame();
tf.setVisible(true);
int initTankCount = Integer.valueOf(PropertyMgr.get("initTankCount"));
// int initTankCount = Integer.valueOf(PropertyMgr.get("initTankCount")); // 初始化敌方坦克
// for (int i = 0; i < initTankCount; i++) {
// // 初始化敌方坦克 tf.tanks.add(tf.gf.createTank(50 + i * 80, 200, Dir.DOWN, Group.BAD, tf));
// for (int i = 0; i < initTankCount; i++) { }
// tf.tanks.add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, tf));
// }
new Thread(() -> new Audio("audio/war1.wav").loop()).start(); new Thread(() -> new Audio("audio/war1.wav").loop()).start();
new Thread(() -> {
while (true) {
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
tf.repaint();
}
}).start();
Client.INSTANCE.connect(); while (true) {
Thread.sleep(50);
tf.repaint();
}
} }
} }

@ -5,22 +5,22 @@ import java.io.IOException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
public class ResourceMgr { public class ResourceMgr {
public static BufferedImage GoodTankL, GoodTankU, GoodTankR, GoodTankD; public static BufferedImage goodTankL, goodTankU, goodTankR, goodTankD;
public static BufferedImage BadTankL, BadTankU, BadTankR, BadTankD; public static BufferedImage badTankL, badTankU, badTankR, badTankD;
public static BufferedImage bulletL, bulletU,bulletR, bulletD; public static BufferedImage bulletL, bulletU,bulletR, bulletD;
public static BufferedImage[] explodes = new BufferedImage[16]; public static BufferedImage[] explodes = new BufferedImage[16];
static { static {
try { try {
GoodTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/GoodTank1.png")); goodTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/GoodTank1.png"));
GoodTankL = ImageUtil.rotateImage(GoodTankU, -90); goodTankL = ImageUtil.rotateImage(goodTankU, -90);
GoodTankR = ImageUtil.rotateImage(GoodTankU, 90); goodTankR = ImageUtil.rotateImage(goodTankU, 90);
GoodTankD = ImageUtil.rotateImage(GoodTankU, 180); goodTankD = ImageUtil.rotateImage(goodTankU, 180);
BadTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/BadTank1.png")); badTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/BadTank1.png"));
BadTankL = ImageUtil.rotateImage(BadTankU, -90); badTankL = ImageUtil.rotateImage(badTankU, -90);
BadTankR = ImageUtil.rotateImage(BadTankU, 90); badTankR = ImageUtil.rotateImage(badTankU, 90);
BadTankD = ImageUtil.rotateImage(BadTankU, 180); badTankD = ImageUtil.rotateImage(badTankU, 180);
bulletU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/bulletU.png")); bulletU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/bulletU.png"));
bulletL = ImageUtil.rotateImage(bulletU, -90); bulletL = ImageUtil.rotateImage(bulletU, -90);

@ -1,59 +1,29 @@
package com.example.tankbattle; package com.example.tankbattle;
import com.example.tankbattle.net.BulletNewMessage; import com.example.tankbattle.abstractfactory.BaseTank;
import com.example.tankbattle.net.Client;
import com.example.tankbattle.net.TankJoinMessage;
import java.awt.Color;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random; import java.util.Random;
import java.util.UUID;
public class Tank { public class Tank extends BaseTank {
private static final int SPEED = 2; private static final int SPEED = 2;
public static int WIDTH = ResourceMgr.GoodTankD.getWidth(); public static int WIDTH = ResourceMgr.goodTankU.getWidth();
public static int HEIGHT = ResourceMgr.GoodTankD.getHeight(); public static int HEIGHT = ResourceMgr.goodTankU.getHeight();
private UUID id = UUID.randomUUID();
Rectangle rect = new Rectangle();
private Random random = new Random(); private Random random = new Random();
private int x,y; int x,y;
private Dir dir = Dir.DOWN; Dir dir = Dir.DOWN;
private boolean moving = false; private boolean moving = true;
private TankFrame tf = null; TankFrame tf = null;
private boolean living = true; private boolean living = true;
private Group group = Group.BAD; FireStrategy fs;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public Tank(TankJoinMessage message) {
this.x = message.x;
this.y = message.y;
this.dir = message.dir;
this.moving = message.moving;
this.group = message.group;
this.id = message.id;
rect.x = this.x;
rect.y = this.y;
rect.width = WIDTH;
rect.height = HEIGHT;
}
public Tank(int x, int y, Dir dir, Group group, TankFrame tf) { public Tank(int x, int y, Dir dir, Group group, TankFrame tf) {
super(); super();
@ -67,17 +37,32 @@ public class Tank {
rect.y = this.y; rect.y = this.y;
rect.width = WIDTH; rect.width = WIDTH;
rect.height = HEIGHT; rect.height = HEIGHT;
if(group == Group.GOOD) {
String goodFSName = PropertyMgr.get("goodFS");
try {
fs = (FireStrategy)Class.forName(goodFSName).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
} else {
fs = new DefaultFireStrategy();
}
} }
public void fire(){ public void fire(){
int bX = this.x + Tank.WIDTH / 2 - Bullet.WIDTH / 2; // fs.fire(this);
int bY = this.y + Tank.HEIGHT / 2 - Bullet.HEIGHT / 2; int bX = this.x + Tank.WIDTH/2 - Bullet.WIDTH/2;
Bullet bullet = new Bullet(this.id, bX, bY, this.dir, this.group, this.tf); int bY = this.y + Tank.HEIGHT/2 - Bullet.HEIGHT/2;
tf.bullets.add(bullet);
Client.INSTANCE.send(new BulletNewMessage(bullet)); Dir[] dirs = Dir.values();
if (this.group == Group.GOOD) { for(Dir dir : dirs) {
new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); tf.gf.createBullet(bX, bY, dir, group, tf);
} }
if(group == Group.GOOD) new Thread(()->new Audio("audio/tank_fire.wav").play()).start();
} }
public Dir getDir() { public Dir getDir() {
@ -105,7 +90,6 @@ public class Tank {
} }
private void move() { private void move() {
if (!living) return;
if (!moving) return; if (!moving) return;
switch (dir) { switch (dir) {
case LEFT: case LEFT:
@ -124,70 +108,45 @@ public class Tank {
break; break;
} }
if (this.group == Group.BAD && random.nextInt(100) > 95)
if (this.group == Group.BAD && random.nextInt(100) > 95) {
this.fire(); this.fire();
}
if (this.group == Group.BAD && random.nextInt(100) > 95) { if (this.group == Group.BAD && random.nextInt(100) > 95)
randomDir(); randomDir();
}
boundsCheck(); boundsCheck();
//update rect
rect.x = this.x; rect.x = this.x;
rect.y = this.y; rect.y = this.y;
} }
private void boundsCheck() { private void boundsCheck() {
if (this.x < 2) { if (this.x < 2) x = 2;
this.x = 2; if (this.y < 28) y = 28;
}
if (this.y < 28) {
this.y = 28;
}
if (this.x > TankFrame.GAME_WIDTH - Tank.WIDTH - 2) { if (this.x > TankFrame.GAME_WIDTH - Tank.WIDTH-2) this.x = TankFrame.GAME_WIDTH - Tank.WIDTH - 2;
this.x = TankFrame.GAME_WIDTH - Tank.WIDTH - 2; if (this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT-2) this.y = TankFrame.GAME_HEIGHT - Tank.HEIGHT-2;
}
if (this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2) {
this.y = TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2;
}
} }
private void randomDir() { private void randomDir() {
this.dir = Dir.values()[random.nextInt(4)]; this.dir = Dir.values()[random.nextInt(4)];
} }
@Override
public void paint(Graphics g) { public void paint(Graphics g) {
// if (!living) { if (!living) tf.tanks.remove(this);
// tf.tanks.remove(this);
// }
Color color = g.getColor();
g.setColor(Color.YELLOW);
g.drawString(id.toString(), this.x, this.y - 20);
g.drawString("live=" + living, x, y - 10);
g.setColor(color);
if (!living) {
moving = false;
Color colorc = g.getColor();
g.setColor(Color.WHITE);
g.drawRect(x, y, WIDTH, HEIGHT);
g.setColor(colorc);
return;
}
switch (dir) { switch (dir) {
case LEFT: case LEFT:
g.drawImage(this.group == Group.GOOD ? ResourceMgr.GoodTankL : ResourceMgr.BadTankL, x, y, null); g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankL : ResourceMgr.badTankL, x, y, null);
break; break;
case UP: case UP:
g.drawImage(this.group == Group.GOOD ? ResourceMgr.GoodTankU : ResourceMgr.BadTankU, x, y, null); g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankU : ResourceMgr.badTankU, x, y, null);
break; break;
case RIGHT: case RIGHT:
g.drawImage(this.group == Group.GOOD ? ResourceMgr.GoodTankR : ResourceMgr.BadTankR, x, y, null); g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankR : ResourceMgr.badTankR, x, y, null);
break; break;
case DOWN: case DOWN:
g.drawImage(this.group == Group.GOOD ? ResourceMgr.GoodTankD : ResourceMgr.BadTankD, x, y, null); g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankD : ResourceMgr.badTankD, x, y, null);
break; break;
default: default:
break; break;
@ -207,24 +166,12 @@ public class Tank {
this.x = x; this.x = x;
} }
public boolean isLiving() {
return living;
}
public void setLiving(boolean living) {
this.living = living;
}
public void setY(int y) { public void setY(int y) {
this.y = y; this.y = y;
} }
@Override
public void die() { public void die() {
this.living = false; this.living = false;
int eX = this.getX() + Tank.WIDTH / 2 - Explode.WIDTH / 2;
int eY = this.getY() + Tank.HEIGHT / 2 - Explode.HEIGHT / 2;
TankFrame.INSTANCE.explodes.add(new Explode(eX, eY));
} }
} }

@ -1,9 +1,10 @@
package com.example.tankbattle; package com.example.tankbattle;
import com.example.tankbattle.net.Client; import com.example.tankbattle.abstractfactory.BaseBullet;
import com.example.tankbattle.net.TankDirChangedMessage; import com.example.tankbattle.abstractfactory.BaseExplode;
import com.example.tankbattle.net.TankStartMovingMessage; import com.example.tankbattle.abstractfactory.BaseTank;
import com.example.tankbattle.net.TankStopMessage; import com.example.tankbattle.abstractfactory.DefaultFactory;
import com.example.tankbattle.abstractfactory.GameFactory;
import java.awt.Color; import java.awt.Color;
import java.awt.Frame; import java.awt.Frame;
@ -14,54 +15,27 @@ import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
public class TankFrame extends Frame { public class TankFrame extends Frame {
public static final TankFrame INSTANCE = new TankFrame(); Tank myTank = new Tank(200, 400, Dir.DOWN, Group.GOOD, this);
Random random = new Random(); public List<BaseBullet> bullets = new ArrayList<>();
public List<BaseTank> tanks = new ArrayList<>();
public List<BaseExplode> explodes = new ArrayList<>();
Tank myTank = new Tank(random.nextInt(GAME_WIDTH), random.nextInt(GAME_HEIGHT), Dir.DOWN, Group.GOOD, this); public GameFactory gf = new DefaultFactory();
List<Bullet> bullets = new ArrayList<>(); public static final int GAME_WIDTH = Integer.valueOf(PropertyMgr.get("gameWidth"));
Map<UUID, Tank> tanks = new HashMap<>();
List<Explode> explodes = new ArrayList<>();
public static final int GAME_HEIGHT = Integer.valueOf(PropertyMgr.get("gameHeight"));
static final int GAME_WIDTH = Integer.valueOf(PropertyMgr.get("gameWidth")); public TankFrame() {
static final int GAME_HEIGHT = Integer.valueOf(PropertyMgr.get("gameHeight"));
public void addBullet(Bullet bullet) {
bullets.add(bullet);
}
public void addTank(Tank tank) {
tanks.put(tank.getId(), tank);
}
public Tank findTankByUUID(UUID id){
return tanks.get(id);
}
public Bullet findBulletByUUID(UUID id) {
for (int i = 0; i < bullets.size(); i++) {
if (bullets.get(i).getId().equals(id)) {
return bullets.get(i);
}
}
return null;
}
private TankFrame() {
setSize(GAME_WIDTH, GAME_HEIGHT); setSize(GAME_WIDTH, GAME_HEIGHT);
setResizable(false); setResizable(false);
setTitle("tank battle"); setTitle("tank battle");
setVisible(true);
this.addKeyListener(new MyKeyListener()); this.addKeyListener(new MyKeyListener());
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
@Override @Override
@ -72,6 +46,7 @@ public class TankFrame extends Frame {
} }
Image offScreenImage = null; Image offScreenImage = null;
@Override @Override
public void update(Graphics g) { public void update(Graphics g) {
if (offScreenImage == null) { if (offScreenImage == null) {
@ -100,17 +75,19 @@ public class TankFrame extends Frame {
bullets.get(i).paint(g); bullets.get(i).paint(g);
} }
tanks.values().stream().forEach((e) -> e.paint(g)); for (int i = 0; i < tanks.size(); i++) {
tanks.get(i).paint(g);
}
for (int i = 0; i < explodes.size(); i++) { for (int i = 0; i < explodes.size(); i++) {
explodes.get(i).paint(g); explodes.get(i).paint(g);
} }
Collection<Tank> values = tanks.values();
for (int i = 0; i < bullets.size(); i++) { for (int i = 0; i < bullets.size(); i++) {
for (Tank value : values) { for (int j = 0; j < tanks.size(); j++)
bullets.get(i).collideWith(value); bullets.get(i).collideWith(tanks.get(j));
}
} }
// for (Iterator<Bullet> it = bullets.iterator(); it.hasNext()) { // for (Iterator<Bullet> it = bullets.iterator(); it.hasNext()) {
// Bullet b = it.next(); // Bullet b = it.next();
// if (!b.live) it.remove(); // if (!b.live) it.remove();
@ -131,23 +108,21 @@ public class TankFrame extends Frame {
switch (key) { switch (key) {
case KeyEvent.VK_LEFT: case KeyEvent.VK_LEFT:
bL = true; bL = true;
setMainTankDir();
break; break;
case KeyEvent.VK_UP: case KeyEvent.VK_UP:
bU = true; bU = true;
setMainTankDir();
break; break;
case KeyEvent.VK_RIGHT: case KeyEvent.VK_RIGHT:
bR = true; bR = true;
setMainTankDir();
break; break;
case KeyEvent.VK_DOWN: case KeyEvent.VK_DOWN:
bD = true; bD = true;
setMainTankDir();
break; break;
default: default:
break; break;
} }
setMainTankDir();
new Thread(()->new Audio("audio/tank_move.wav").play()).start(); new Thread(()->new Audio("audio/tank_move.wav").play()).start();
} }
@ -157,19 +132,15 @@ public class TankFrame extends Frame {
switch (key) { switch (key) {
case KeyEvent.VK_LEFT: case KeyEvent.VK_LEFT:
bL = false; bL = false;
setMainTankDir();
break; break;
case KeyEvent.VK_UP: case KeyEvent.VK_UP:
bU = false; bU = false;
setMainTankDir();
break; break;
case KeyEvent.VK_RIGHT: case KeyEvent.VK_RIGHT:
bR = false; bR = false;
setMainTankDir();
break; break;
case KeyEvent.VK_DOWN: case KeyEvent.VK_DOWN:
bD = false; bD = false;
setMainTankDir();
break; break;
case KeyEvent.VK_CONTROL: case KeyEvent.VK_CONTROL:
myTank.fire(); myTank.fire();
@ -177,44 +148,27 @@ public class TankFrame extends Frame {
default: default:
break; break;
} }
setMainTankDir();
} }
private void setMainTankDir() { private void setMainTankDir() {
Dir dir = myTank.getDir();
if (!bL && !bU && !bR && !bD) { if (!bL && !bU && !bR && !bD) {
myTank.setMoving(false); myTank.setMoving(false);
Client.INSTANCE.send(new TankStopMessage(getMainTank()));
} else { } else {
if (bL) { myTank.setMoving(true);
if (bL)
myTank.setDir(Dir.LEFT); myTank.setDir(Dir.LEFT);
} if (bU)
if (bU) {
myTank.setDir(Dir.UP); myTank.setDir(Dir.UP);
} if (bR)
if (bR) {
myTank.setDir(Dir.RIGHT); myTank.setDir(Dir.RIGHT);
} if (bD)
if (bD) {
myTank.setDir(Dir.DOWN); myTank.setDir(Dir.DOWN);
}
if (!myTank.isMoving()) {
Client.INSTANCE.send(new TankStartMovingMessage(getMainTank()));
}
myTank.setMoving(true);
if (dir != myTank.getDir()) {
Client.INSTANCE.send(new TankDirChangedMessage(myTank));
}
} }
} }
} }
public Tank getMainTank() {
return this.myTank;
}
} }

@ -0,0 +1,9 @@
package com.example.tankbattle.abstractfactory;
import java.awt.Graphics;
public abstract class BaseBullet {
public abstract void paint(Graphics g);
public abstract void collideWith(BaseTank tank);
}

@ -0,0 +1,7 @@
package com.example.tankbattle.abstractfactory;
import java.awt.Graphics;
public abstract class BaseExplode {
public abstract void paint(Graphics g);
}

@ -0,0 +1,23 @@
package com.example.tankbattle.abstractfactory;
import com.example.tankbattle.Group;
import java.awt.Graphics;
import java.awt.Rectangle;
public abstract class BaseTank {
public Group group = Group.BAD;
public Rectangle rect = new Rectangle();
public abstract void paint(Graphics g);
public Group getGroup() {
return this.group;
}
public abstract void die();
public abstract int getX();
public abstract int getY();
}

@ -0,0 +1,25 @@
package com.example.tankbattle.abstractfactory;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Explode;
import com.example.tankbattle.Group;
import com.example.tankbattle.Tank;
import com.example.tankbattle.TankFrame;
public class DefaultFactory extends GameFactory {
@Override
public BaseTank createTank(int x, int y, Dir dir, Group group, TankFrame tf) {
return new Tank(x, y, dir, group, tf);
}
@Override
public BaseExplode createExplode(int x, int y, TankFrame tf) {
return new Explode(x, y, tf);
}
@Override
public BaseBullet createBullet(int x, int y, Dir dir, Group group, TankFrame tf) {
return new Bullet(x, y, dir, group, tf);
}
}

@ -0,0 +1,14 @@
package com.example.tankbattle.abstractfactory;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Group;
import com.example.tankbattle.TankFrame;
public abstract class GameFactory {
public abstract BaseTank createTank(int x, int y, Dir dir, Group group, TankFrame tf);
public abstract BaseExplode createExplode(int x, int y, TankFrame tf);
public abstract BaseBullet createBullet(int x, int y, Dir dir, Group group, TankFrame tf);
}

@ -0,0 +1,106 @@
package com.example.tankbattle.abstractfactory;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Explode;
import com.example.tankbattle.Group;
import com.example.tankbattle.ResourceMgr;
import com.example.tankbattle.Tank;
import com.example.tankbattle.TankFrame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
public class RectBullet extends BaseBullet {
private static final int SPEED = 6;
public static int WIDTH = ResourceMgr.bulletD.getWidth();
public static int HEIGHT = ResourceMgr.bulletD.getHeight();
Rectangle rect = new Rectangle();
private int x, y;
private Dir dir;
private boolean living = true;
TankFrame tf = null;
private Group group = Group.BAD;
public RectBullet(int x, int y, Dir dir, Group group, TankFrame tf) {
this.x = x;
this.y = y;
this.dir = dir;
this.group = group;
this.tf = tf;
rect.x = this.x;
rect.y = this.y;
rect.width = WIDTH;
rect.height = HEIGHT;
tf.bullets.add(this);
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Override
public void paint(Graphics g) {
if (!living) {
tf.bullets.remove(this);
}
Color c = g.getColor();
g.setColor(Color.YELLOW);
g.fillRect(x, y, 20, 20);
g.setColor(c);
move();
}
private void move() {
switch (dir) {
case LEFT:
x -= SPEED;
break;
case UP:
y -= SPEED;
break;
case RIGHT:
x += SPEED;
break;
case DOWN:
y += SPEED;
break;
default:
break;
}
rect.x = this.x;
rect.y = this.y;
if (x < 0 || y < 0 || x > TankFrame.GAME_WIDTH || y > TankFrame.GAME_HEIGHT) living = false;
}
@Override
public void collideWith(BaseTank tank) {
if (this.group == tank.getGroup()) return;
if (this.rect.intersects(tank.rect)) {
tank.die();
this.die();
int eX = tank.getX() + Tank.WIDTH / 2 - Explode.WIDTH / 2;
int eY = tank.getY() + Tank.HEIGHT / 2 - Explode.HEIGHT / 2;
tf.explodes.add(tf.gf.createExplode(eX, eY, tf));
}
}
private void die() {
this.living = false;
}
}

@ -0,0 +1,45 @@
package com.example.tankbattle.abstractfactory;
import com.example.tankbattle.Audio;
import com.example.tankbattle.ResourceMgr;
import com.example.tankbattle.TankFrame;
import java.awt.Color;
import java.awt.Graphics;
public class RectExplode extends BaseExplode {
public static int WIDTH = ResourceMgr.explodes[0].getWidth();
public static int HEIGHT = ResourceMgr.explodes[0].getHeight();
private int x, y;
TankFrame tf = null;
private int step = 0;
public RectExplode(int x, int y, TankFrame tf) {
this.x = x;
this.y = y;
this.tf = tf;
new Thread(() -> new Audio("audio/explode.wav").play()).start();
}
@Override
public void paint(Graphics g) {
// g.drawImage(ResourceMgr.explodes[step++], x, y, null);
Color c = g.getColor();
g.setColor(Color.RED);
g.fillRect(x, y, 10*step, 10*step);
step++;
if (step >= 15) {
tf.explodes.remove(this);
}
g.setColor(c);
}
}

@ -0,0 +1,23 @@
package com.example.tankbattle.abstractfactory;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Group;
import com.example.tankbattle.TankFrame;
public class RectFactory extends GameFactory {
@Override
public BaseTank createTank(int x, int y, Dir dir, Group group, TankFrame tf) {
return new RectTank(x, y, dir, group, tf);
}
@Override
public BaseExplode createExplode(int x, int y, TankFrame tf) {
return new RectExplode(x, y, tf);
}
@Override
public BaseBullet createBullet(int x, int y, Dir dir, Group group, TankFrame tf) {
return new RectBullet(x, y, dir, group, tf);
}
}

@ -0,0 +1,193 @@
package com.example.tankbattle.abstractfactory;
import com.example.tankbattle.Audio;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.DefaultFireStrategy;
import com.example.tankbattle.Dir;
import com.example.tankbattle.FireStrategy;
import com.example.tankbattle.Group;
import com.example.tankbattle.PropertyMgr;
import com.example.tankbattle.ResourceMgr;
import com.example.tankbattle.TankFrame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class RectTank extends BaseTank{
private static final int SPEED = 2;
public static int WIDTH = ResourceMgr.goodTankU.getWidth();
public static int HEIGHT = ResourceMgr.goodTankU.getHeight();
public Rectangle rect = new Rectangle();
private Random random = new Random();
int x, y;
Dir dir = Dir.DOWN;
private boolean moving = true;
TankFrame tf = null;
private boolean living = true;
Group group = Group.BAD;
FireStrategy fs;
public RectTank(int x, int y, Dir dir, Group group, TankFrame tf) {
super();
this.x = x;
this.y = y;
this.dir = dir;
this.group = group;
this.tf = tf;
rect.x = this.x;
rect.y = this.y;
rect.width = WIDTH;
rect.height = HEIGHT;
if(group == Group.GOOD) {
String goodFSName = PropertyMgr.get("goodFS");
try {
fs = (FireStrategy)Class.forName(goodFSName).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
} else {
fs = new DefaultFireStrategy();
}
}
public void fire(){
// fs.fire(this);
int bX = this.x + RectTank.WIDTH / 2 - Bullet.WIDTH / 2;
int bY = this.y + RectTank.HEIGHT / 2 - Bullet.HEIGHT / 2;
Dir[] dirs = Dir.values();
for (Dir dir : dirs) {
tf.gf.createBullet(bX, bY, dir, group, tf);
}
if (group == Group.GOOD)
new Thread(() -> new Audio("audio/tank_fire.wav").play()).start();
}
public Dir getDir() {
return dir;
}
@Override
public int getX() {
return x;
}
@Override
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Override
public int getY() {
return y;
}
public boolean isMoving() {
return moving;
}
private void move() {
if (!moving) return;
switch (dir) {
case LEFT:
x -= SPEED;
break;
case UP:
y -= SPEED;
break;
case RIGHT:
x += SPEED;
break;
case DOWN:
y += SPEED;
break;
default:
break;
}
if (this.group == Group.BAD && random.nextInt(100) > 95)
this.fire();
if (this.group == Group.GOOD && random.nextInt(100) > 95)
randomDir();
boundsCheck();
// update rect
rect.x = this.x;
rect.y = this.y;
}
private void boundsCheck() {
if (this.x < 2)
x = 2;
if (this.y < 28)
y = 28;
if (this.x > TankFrame.GAME_WIDTH - RectTank.WIDTH-2)
x = TankFrame.GAME_WIDTH - RectTank.WIDTH;
if (this.y > TankFrame.GAME_HEIGHT - RectTank.HEIGHT-2)
y = TankFrame.GAME_HEIGHT - RectTank.HEIGHT;
}
private void randomDir() {
this.dir = Dir.values()[random.nextInt(4)];
}
@Override
public void paint(Graphics g) {
if (!living) tf.tanks.remove(this);
Color c = g.getColor();
g.setColor(group == Group.GOOD ? Color.RED : Color.BLUE);
g.fillRect(x, y, 40, 40);
g.setColor(c);
move();
}
public void setDir(Dir dir) {
this.dir = dir;
}
public void setMoving(boolean moving) {
this.moving = moving;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
@Override
public void die() {
this.living = false;
}
}

@ -0,0 +1,9 @@
package com.example.tankbattle.abstractfactory.demo;
public class AK47 extends Weapon {
@Override
public void shoot() {
System.out.println("tutututututuututtu");
}
}

@ -0,0 +1,7 @@
package com.example.tankbattle.abstractfactory.demo;
public abstract class AbstractFactory {
abstract Food createFood();
abstract Vehicle createVehicle();
abstract Weapon createWeapon();
}

@ -0,0 +1,9 @@
package com.example.tankbattle.abstractfactory.demo;
public class Bread extends Food {
@Override
public void printName() {
System.out.println("breadbreadbreadbreadbreadbread");
}
}

@ -0,0 +1,9 @@
package com.example.tankbattle.abstractfactory.demo;
public class Broom extends Vehicle {
@Override
public void go() {
System.out.println("broom flybroom flybroom flybroom flybroom flybroom fly");
}
}

@ -0,0 +1,9 @@
package com.example.tankbattle.abstractfactory.demo;
public class Car extends Vehicle {
@Override
public void go() {
System.out.println("car move xxxxx");
}
}

@ -0,0 +1,6 @@
package com.example.tankbattle.abstractfactory.demo;
public abstract class Food {
public abstract void printName();
}

@ -0,0 +1,19 @@
package com.example.tankbattle.abstractfactory.demo;
public class MagicFactory extends AbstractFactory{
@Override
Food createFood() {
return new MushRoom();
}
@Override
Vehicle createVehicle() {
return new Broom();
}
@Override
Weapon createWeapon() {
return new MagicStick();
}
}

@ -0,0 +1,9 @@
package com.example.tankbattle.abstractfactory.demo;
public class MagicStick extends Weapon {
@Override
public void shoot() {
System.out.println("magic stickmagic stickmagic stickmagic stickmagic stick");
}
}

@ -0,0 +1,20 @@
package com.example.tankbattle.abstractfactory.demo;
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.go();
AK47 aK47 = new AK47();
aK47.shoot();
Bread bread = new Bread();
bread.printName();
AbstractFactory factory = new ModernFactory();
Vehicle vehicle = factory.createVehicle();
vehicle.go();
Weapon weapon = factory.createWeapon();
weapon.shoot();
Food food = factory.createFood();
food.printName();
}
}

@ -0,0 +1,18 @@
package com.example.tankbattle.abstractfactory.demo;
public class ModernFactory extends AbstractFactory{
@Override
Food createFood() {
return new Bread();
}
@Override
Vehicle createVehicle() {
return new Car();
}
@Override
Weapon createWeapon() {
return new AK47();
}
}

@ -0,0 +1,9 @@
package com.example.tankbattle.abstractfactory.demo;
public class MushRoom extends Food {
@Override
public void printName() {
System.out.println("mushRoommushRoommushRoommushRoommushRoommushRoom");
}
}

@ -0,0 +1,5 @@
package com.example.tankbattle.abstractfactory.demo;
public abstract class Vehicle {
public abstract void go();
}

@ -0,0 +1,17 @@
package com.example.tankbattle.abstractfactory.demo;
import com.example.tankbattle.factorymethod.Broom;
import com.example.tankbattle.factorymethod.Car;
public abstract class VehicleFactory {
public Car createCar(){
// pre-process
return new Car();
}
public Broom createBroom(){
// pre-process
return new Broom();
}
}

@ -0,0 +1,5 @@
package com.example.tankbattle.abstractfactory.demo;
public abstract class Weapon {
public abstract void shoot();
}

@ -0,0 +1,9 @@
package com.example.tankbattle.factorymethod;
public class Broom implements Moveable{
@Override
public void go() {
System.out.println("broom fly xxxxxxxx");
}
}

@ -0,0 +1,9 @@
package com.example.tankbattle.factorymethod;
public class Car implements Moveable {
@Override
public void go() {
System.out.println("car move xxxxx");
}
}

@ -0,0 +1,10 @@
package com.example.tankbattle.factorymethod;
public class CarFactory {
public Car create() {
// log
System.out.println("xxxxxxxxxxx");
return new Car();
}
}

@ -0,0 +1,9 @@
package com.example.tankbattle.factorymethod;
public class Main {
public static void main(String[] args) {
Moveable moveable = new CarFactory().create();
moveable.go();
}
}

@ -0,0 +1,5 @@
package com.example.tankbattle.factorymethod;
public interface Moveable {
void go();
}

@ -0,0 +1,9 @@
package com.example.tankbattle.factorymethod;
public class Plane implements Moveable {
@Override
public void go() {
System.out.println("plane go xxxx");
}
}

@ -0,0 +1,14 @@
package com.example.tankbattle.factorymethod;
public class SimpleVehicleFactory {
public Car createCar() {
// pre-process
return new Car();
}
public Broom createBroom() {
// pre-process
return new Broom();
}
}

@ -1,96 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Group;
import com.example.tankbattle.TankFrame;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
public class BulletNewMessage extends Message {
UUID playerID;
UUID id;
int x, y;
Dir dir;
Group group;
public BulletNewMessage() {
}
public BulletNewMessage(Bullet bullet) {
this.playerID = bullet.getPlayerId();
this.id = bullet.getId();
this.x = bullet.getX();
this.y = bullet.getY();
this.dir = bullet.getDir();
this.group = bullet.getGroup();
}
@Override
public void handle() {
if (this.playerID.equals(TankFrame.INSTANCE.getMainTank().getId())) {
return;
}
Bullet bullet = new Bullet(this.playerID, x, y, dir, group, TankFrame.INSTANCE);
bullet.setId(this.id);
TankFrame.INSTANCE.addBullet(bullet);
}
@Override
public byte[] toBytes() {
byte[] bytes = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos)) {
dos.writeLong(this.playerID.getMostSignificantBits());
dos.writeLong(this.playerID.getLeastSignificantBits());
dos.writeLong(id.getMostSignificantBits());
dos.writeLong(id.getLeastSignificantBits());
dos.writeInt(x);
dos.writeInt(y);
dos.writeInt(dir.ordinal());
dos.writeInt(group.ordinal());
dos.flush();
bytes = baos.toByteArray();
} catch (Exception exception) {
exception.printStackTrace();
}
return bytes;
}
@Override
public void parse(byte[] bytes) {
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes))) {
this.playerID = new UUID(dis.readLong(), dis.readLong());
this.id = new UUID(dis.readLong(), dis.readLong());
this.x = dis.readInt();
this.y = dis.readInt();
this.dir = Dir.values()[dis.readInt()];
this.group = Group.values()[dis.readInt()];
} catch (IOException exception) {
exception.printStackTrace();
}
}
@Override
public MessageType getMessageType() {
return MessageType.BulletNew;
}
@Override
public String toString() {
return "BulletNewMessage{" +
"playerID=" + playerID +
", id=" + id +
", x=" + x +
", y=" + y +
", dir=" + dir +
", group=" + group +
'}';
}
}

@ -1,53 +0,0 @@
package com.example.tankbattle.net;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
public class Client {
public static final Client INSTANCE = new Client();
private Client() {
}
private Channel channel;
public void connect() {
EventLoopGroup group = new NioEventLoopGroup(1);
Bootstrap bootstrap = new Bootstrap();
try {
ChannelFuture channelFuture = bootstrap.group(group).channel(NioSocketChannel.class).handler(new ClientChannelInitializer())
.connect("localhost", 8888);
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
System.out.println("not connected");
} else {
System.out.println("connected");
channel = future.channel();
}
}
});
channelFuture.sync();
channelFuture.channel().closeFuture().sync();
System.out.println("connection closed");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
public void send(Message message) {
System.out.println("send " + message.toString());
channel.writeAndFlush(message);
}
public void closeConnect(){
}
}

@ -1,15 +0,0 @@
package com.example.tankbattle.net;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
.addLast(new MessageEncoder())
.addLast(new MessageDecoder())
.addLast(new ClientHandler());
}
}

@ -1,18 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.TankFrame;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class ClientHandler extends SimpleChannelInboundHandler<Message> {
@Override
public void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception {
System.out.println(msg);
msg.handle();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(new TankJoinMessage(TankFrame.INSTANCE.getMainTank()));
}
}

@ -1,8 +0,0 @@
package com.example.tankbattle.net;
public abstract class Message {
public abstract void handle();
public abstract byte[] toBytes();
public abstract void parse(byte[] bytes);
public abstract MessageType getMessageType();
}

@ -1,30 +0,0 @@
package com.example.tankbattle.net;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
public class MessageDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (in.readableBytes() < 8) {
return;
}
in.markReaderIndex();
MessageType messageType = MessageType.values()[in.readInt()];
int length = in.readInt();
if (in.readableBytes() < length) {
in.resetReaderIndex();
return;
}
byte[] bytes = new byte[length];
in.readBytes(bytes);
Message message = (Message) Class.forName("com.example.tankbattle.net." + messageType.toString() + "Message").getDeclaredConstructor().newInstance();
message.parse(bytes);
out.add(message);
}
}

@ -1,16 +0,0 @@
package com.example.tankbattle.net;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
public class MessageEncoder extends MessageToByteEncoder<Message> {
@Override
protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
out.writeInt(msg.getMessageType().ordinal());
byte[] data = msg.toBytes();
out.writeInt(data.length);
out.writeBytes(data);
}
}

@ -1,5 +0,0 @@
package com.example.tankbattle.net;
public enum MessageType {
TankJoin, TankDirChanged, TankStop, TankStartMoving, BulletNew, TankDie,
}

@ -1,44 +0,0 @@
package com.example.tankbattle.net;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.GlobalEventExecutor;
public class Server {
public static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
public void serverStart() {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(2);
try {
ServerBootstrap bootstrap = new ServerBootstrap();
ChannelFuture channelFuture = bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline channelPipeline = ch.pipeline();
channelPipeline.addLast(new MessageEncoder())
.addLast(new MessageDecoder())
.addLast(new ServerChildHandler());
}
}).bind(8888).sync();
ServerFrame.INSTANCE.updateServerMessage("server started!");
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}

@ -1,48 +0,0 @@
package com.example.tankbattle.net;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ServerChildHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Server.clients.add(ctx.channel());
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ServerFrame.INSTANCE.updateClientMessage(msg.toString());
Server.clients.writeAndFlush(msg);
/*ByteBuf buf = null;
try {
buf = (ByteBuf)msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.getBytes(buf.readerIndex(), bytes);
String s = new String(bytes);
if(s.equals("_bye_")) {
System.out.println("<22>ͻ<EFBFBD><CDBB><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>˳<EFBFBD>");
Server.clients.remove(ctx.channel());
ctx.close();
} else {
Server.clients.writeAndFlush(msg);
}*/
//System.out.println(buf);
//System.out.println(buf.refCnt());
/*} finally {
//if(buf != null && buf) ReferenceCountUtil.release(buf);
//System.out.println(buf.refCnt());
}*/
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
Server.clients.remove(ctx.channel());
ctx.close();
}
}

@ -1,51 +0,0 @@
package com.example.tankbattle.net;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class ServerFrame extends Frame {
public static final ServerFrame INSTANCE = new ServerFrame();
Button btnStart = new Button("start");
TextArea textLeft = new TextArea();
TextArea textRight = new TextArea();
Server server = new Server();
public ServerFrame() {
this.setSize(1600, 600);
this.setLocation(300, 30);
this.add(btnStart, BorderLayout.NORTH);
Panel panel = new Panel(new GridLayout(1, 2));
panel.add(textLeft);
panel.add(textRight);
this.add(panel);
textLeft.setFont(new Font("verderna", Font.PLAIN, 25));
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
ServerFrame.INSTANCE.setVisible(true);
ServerFrame.INSTANCE.server.serverStart();
}
public void updateServerMessage(String message) {
this.textLeft.setText(textLeft.getText() + message + System.lineSeparator());
}
public void updateClientMessage(String message) {
this.textRight.setText(textRight.getText() + message + System.lineSeparator());
}
}

@ -1,96 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.Tank;
import com.example.tankbattle.TankFrame;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
public class TankDieMessage extends Message{
UUID bulletId;
UUID id;
public TankDieMessage() {
}
public TankDieMessage(UUID playerId, UUID id) {
this.bulletId = playerId;
this.id = id;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
@Override
public void handle() {
System.out.println("we got a tank die: " + id);
System.out.println("and my tank is: " + TankFrame.INSTANCE.getMainTank().getId());
Tank tank = TankFrame.INSTANCE.findTankByUUID(id);
System.out.println("i found a tank with this id: " + tank);
Bullet bullet = TankFrame.INSTANCE.findBulletByUUID(bulletId);
if (bullet != null) {
bullet.die();
}
if (this.id.equals(TankFrame.INSTANCE.getMainTank().getId())) {
TankFrame.INSTANCE.getMainTank().die();
} else {
Tank tanka = TankFrame.INSTANCE.findTankByUUID(id);
if (tanka != null) {
tanka.die();
}
}
}
@Override
public byte[] toBytes() {
byte[] bytes = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos)) {
dos.writeLong(bulletId.getMostSignificantBits());
dos.writeLong(bulletId.getLeastSignificantBits());
dos.writeLong(id.getMostSignificantBits());
dos.writeLong(id.getLeastSignificantBits());
dos.flush();
bytes = baos.toByteArray();
} catch (Exception exception) {
exception.printStackTrace();
}
return bytes;
}
@Override
public void parse(byte[] bytes) {
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes))) {
this.bulletId = new UUID(dis.readLong(), dis.readLong());
this.id = new UUID(dis.readLong(), dis.readLong());
} catch (IOException exception) {
exception.printStackTrace();
}
}
@Override
public MessageType getMessageType() {
return MessageType.TankDie;
}
@Override
public String toString() {
return "TankDieMessage{" +
"bulletId=" + bulletId +
", id=" + id +
'}';
}
}

@ -1,132 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Tank;
import com.example.tankbattle.TankFrame;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
public class TankDirChangedMessage extends Message{
UUID id;
Dir dir;
int x, y;
public TankDirChangedMessage() {
}
public TankDirChangedMessage(UUID id, int x, int y , Dir dir) {
super();
this.id = id;
this.x = x;
this.y = y;
this.dir = dir;
}
public TankDirChangedMessage(Tank tank) {
this.id = tank.getId();
this.dir = tank.getDir();
this.x = tank.getX();
this.y = tank.getY();
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Dir getDir() {
return dir;
}
public void setDir(Dir dir) {
this.dir = dir;
}
@Override
public void handle() {
if (this.id.equals(TankFrame.INSTANCE.getMainTank().getId())) {
return;
}
Tank tank = TankFrame.INSTANCE.findTankByUUID(this.id);
if (tank != null) {
tank.setMoving(true);
tank.setX(this.x);
tank.setY(this.y);
tank.setDir(this.dir);
}
}
@Override
public byte[] toBytes() {
byte[] bytes = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos)) {
dos.writeLong(id.getMostSignificantBits());
dos.writeLong(id.getLeastSignificantBits());
dos.writeInt(x);
dos.writeInt(y);
dos.writeInt(dir.ordinal());
dos.flush();
bytes = baos.toByteArray();
} catch (Exception exception) {
exception.printStackTrace();
}
return bytes;
}
@Override
public void parse(byte[] bytes) {
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes))) {
this.id = new UUID(dis.readLong(), dis.readLong());
this.x = dis.readInt();
this.y = dis.readInt();
this.dir = Dir.values()[dis.readInt()];
} catch (IOException exception) {
exception.printStackTrace();
}
}
@Override
public MessageType getMessageType() {
return MessageType.TankDirChanged;
}
@Override
public String toString() {
return "TankDirChangedMessage{" +
"id=" + id +
", dir=" + dir +
", x=" + x +
", y=" + y +
'}';
}
}

@ -1,109 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Group;
import com.example.tankbattle.Tank;
import com.example.tankbattle.TankFrame;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
public class TankJoinMessage extends Message{
public int x;
public int y;
public Dir dir;
public boolean moving;
public Group group;
public UUID id;
public TankJoinMessage() {
}
public TankJoinMessage(int x, int y, Dir dir, boolean moving, Group group, UUID id) {
super();
this.x = x;
this.y = y;
this.dir = dir;
this.moving = moving;
this.group = group;
this.id = id;
}
public TankJoinMessage(Tank tank) {
this.x = tank.getX();
this.y = tank.getY();
this.dir = tank.getDir();
this.group = tank.getGroup();
this.moving = tank.isMoving();
this.id = tank.getId();
}
@Override
public void parse(byte[] bytes) {
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes))) {
this.x = dis.readInt();
this.y = dis.readInt();
this.dir = Dir.values()[dis.readInt()];
this.moving = dis.readBoolean();
this.group = Group.values()[dis.readInt()];
this.id = new UUID(dis.readLong(), dis.readLong());
} catch (IOException exception) {
exception.printStackTrace();
}
}
@Override
public byte[] toBytes() {
byte[] bytes = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos)) {
dos.writeInt(x);
dos.writeInt(y);
dos.writeInt(dir.ordinal());
dos.writeBoolean(moving);
dos.writeInt(group.ordinal());
dos.writeLong(id.getMostSignificantBits());
dos.writeLong(id.getLeastSignificantBits());
dos.flush();
bytes = baos.toByteArray();
} catch (Exception exception) {
exception.printStackTrace();
}
return bytes;
}
@Override
public void handle() {
if (this.id.equals(TankFrame.INSTANCE.getMainTank().getId()) ||
TankFrame.INSTANCE.findTankByUUID(this.id) != null) {
return;
}
Tank tank = new Tank(this);
TankFrame.INSTANCE.addTank(tank);
Client.INSTANCE.send(new TankJoinMessage(TankFrame.INSTANCE.getMainTank()));
}
@Override
public MessageType getMessageType() {
return MessageType.TankJoin;
}
@Override
public String toString() {
return "TankJoinMessage{" +
"x=" + x +
", y=" + y +
", dir=" + dir +
", moving=" + moving +
", group=" + group +
", id=" + id +
'}';
}
}

@ -1,131 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Tank;
import com.example.tankbattle.TankFrame;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
public class TankStartMovingMessage extends Message{
UUID id;
int x, y;
Dir dir;
public TankStartMovingMessage() {
}
public TankStartMovingMessage(UUID id, int x, int y, Dir dir) {
this.id = id;
this.x = x;
this.y = y;
this.dir = dir;
}
public TankStartMovingMessage(Tank tank) {
this.id = tank.getId();
this.x = tank.getX();
this.y = tank.getY();
this.dir = tank.getDir();
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Dir getDir() {
return dir;
}
public void setDir(Dir dir) {
this.dir = dir;
}
@Override
public void handle() {
if (this.id.equals(TankFrame.INSTANCE.getMainTank().getId())) {
return;
}
Tank tank = TankFrame.INSTANCE.findTankByUUID(this.id);
if (tank != null) {
tank.setMoving(true);
tank.setX(this.x);
tank.setY(this.y);
tank.setDir(this.dir);
}
}
@Override
public byte[] toBytes() {
byte[] bytes = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos)) {
dos.writeLong(id.getMostSignificantBits());
dos.writeLong(id.getLeastSignificantBits());
dos.writeInt(x);
dos.writeInt(y);
dos.writeInt(dir.ordinal());
dos.flush();
bytes = baos.toByteArray();
} catch (Exception exception) {
exception.printStackTrace();
}
return bytes;
}
@Override
public void parse(byte[] bytes) {
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes))) {
this.id = new UUID(dis.readLong(), dis.readLong());
this.x = dis.readInt();
this.y = dis.readInt();
this.dir = Dir.values()[dis.readInt()];
} catch (IOException exception) {
exception.printStackTrace();
}
}
@Override
public MessageType getMessageType() {
return MessageType.TankStartMoving;
}
@Override
public String toString() {
return "TankStartMovingMessage{" +
"id=" + id +
", x=" + x +
", y=" + y +
", dir=" + dir +
'}';
}
}

@ -1,115 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Tank;
import com.example.tankbattle.TankFrame;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
public class TankStopMessage extends Message{
UUID id;
private int x;
private int y;
public TankStopMessage() {}
public TankStopMessage(UUID id, int x, int y) {
this.id = id;
this.x = x;
this.y = y;
}
public TankStopMessage(Tank tank) {
this.id = tank.getId();
this.x = tank.getX();
this.y = tank.getY();
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public void handle() {
if (this.id.equals(TankFrame.INSTANCE.getMainTank().getId())) {
return;
}
Tank tank = TankFrame.INSTANCE.findTankByUUID(this.id);
if (tank != null) {
tank.setMoving(false);
tank.setX(this.x);
tank.setY(this.y);
}
}
@Override
public byte[] toBytes() {
byte[] bytes = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos)) {
dos.writeLong(id.getMostSignificantBits());
dos.writeLong(id.getLeastSignificantBits());
dos.writeInt(x);
dos.writeInt(y);
dos.flush();
bytes = baos.toByteArray();
} catch (Exception exception) {
exception.printStackTrace();
}
return bytes;
}
@Override
public void parse(byte[] bytes) {
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes))) {
this.id = new UUID(dis.readLong(), dis.readLong());
this.x = dis.readInt();
this.y = dis.readInt();
} catch (IOException exception) {
exception.printStackTrace();
}
}
@Override
public MessageType getMessageType() {
return MessageType.TankStop;
}
@Override
public String toString() {
return "TankStopMessage{" +
"id=" + id +
", x=" + x +
", y=" + y +
'}';
}
}

@ -3,4 +3,7 @@ initTankCount=10
tankSpeed=5 tankSpeed=5
bulletSpeed=10 bulletSpeed=10
gameWidth=1080 gameWidth=1080
gameHeight=720 gameHeight=720
#fireStrategy
goodFS=com.example.tankbattle.FourDirFireStrategy
badFS=com.example.tankbattle.DefaultFireStrategy

@ -1,42 +0,0 @@
package com.example.tankbattle;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
class ImageRotateTest {
@Test
void test() {
try {
BufferedImage tankL = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/tankL.gif"));
tankL = rotateImage(tankL, 90);
Assertions.assertNotNull(tankL);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public BufferedImage rotateImage(final BufferedImage bufferedimage,
final int degree) {
int w = bufferedimage.getWidth();
int h = bufferedimage.getHeight();
int type = bufferedimage.getColorModel().getTransparency();
BufferedImage img;
Graphics2D graphics2d;
(graphics2d = (img = new BufferedImage(w, h, type))
.createGraphics()).setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);
graphics2d.drawImage(bufferedimage, 0, 0, null);
graphics2d.dispose();
return img;
}
}

@ -16,9 +16,10 @@ public class ImageTest {
public void test(){ public void test(){
System.out.println(ImageTest.class.getClassLoader()); System.out.println(ImageTest.class.getClassLoader());
try { try {
BufferedImage image = ImageIO.read(new File("/images/bulletD.gif")); BufferedImage image = ImageIO.read(new File("C:/work/javaprojects/Tank_60/src/images/bulletD.gif"));
assertNotNull(image); assertNotNull(image);
BufferedImage image2 = ImageIO.read(ImageTest.class.getClassLoader().getResourceAsStream("src/images/bulletD.gif")); BufferedImage image2 = ImageIO.read(ImageTest.class.getClassLoader().getResourceAsStream("src/images" +
"/bulletD.gif"));
assertNotNull(image2); assertNotNull(image2);
} catch (IOException exception) { } catch (IOException exception) {
exception.printStackTrace(); exception.printStackTrace();

@ -1,69 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Dir;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TankDirChangedMessageCoderTest {
@Test
void encode() {
EmbeddedChannel embeddedChannel = new EmbeddedChannel();
UUID id = UUID.randomUUID();
TankStartMovingMessage message = new TankStartMovingMessage(id, 5, 10, Dir.LEFT);
embeddedChannel.pipeline()
.addLast(new MessageEncoder());
embeddedChannel.writeOutbound(message);
ByteBuf buf = (ByteBuf) embeddedChannel.readOutbound();
MessageType messageType = MessageType.values()[buf.readInt()];
assertEquals(MessageType.TankStartMoving, messageType);
int length = buf.readInt();
assertEquals(28, length);
UUID uuid = new UUID(buf.readLong(), buf.readLong());
int x = buf.readInt();
int y = buf.readInt();
int dirOrdinal = buf.readInt();
Dir dir = Dir.values()[dirOrdinal];
assertEquals(5, x);
assertEquals(10, y);
assertEquals(Dir.LEFT, dir);
assertEquals(id, uuid);
}
@Test
void testDecoder() {
EmbeddedChannel ch = new EmbeddedChannel();
UUID id = UUID.randomUUID();
TankStartMovingMessage message = new TankStartMovingMessage(id, 5, 10, Dir.LEFT);
ch.pipeline()
.addLast(new MessageDecoder());
ByteBuf buf = Unpooled.buffer();
buf.writeInt(MessageType.TankStartMoving.ordinal());
byte[] bytes = message.toBytes();
buf.writeInt(bytes.length);
buf.writeBytes(bytes);
ch.writeInbound(buf.duplicate());
TankStartMovingMessage msg = (TankStartMovingMessage) ch.readInbound();
assertEquals(5, msg.getX());
assertEquals(10, msg.getY());
assertEquals(Dir.LEFT, msg.getDir());
assertEquals(id, msg.getId());
}
}

@ -1,83 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Group;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.*;
class TankJoinMessageCoderTest {
@Test
void testEncoder() {
EmbeddedChannel ch = new EmbeddedChannel();
UUID id = UUID.randomUUID();
TankJoinMessage msg = new TankJoinMessage(5, 10, Dir.DOWN, true, Group.BAD, id);
ch.pipeline()
.addLast(new MessageEncoder());
ch.writeOutbound(msg);
ByteBuf buf = (ByteBuf)ch.readOutbound();
MessageType messageType = MessageType.values()[buf.readInt()];
assertEquals(MessageType.TankJoin, messageType);
int length = buf.readInt();
assertEquals(33, length);
int x = buf.readInt();
int y = buf.readInt();
int dirOrdinal = buf.readInt();
Dir dir = Dir.values()[dirOrdinal];
boolean moving = buf.readBoolean();
int groupOrdinal = buf.readInt();
Group g = Group.values()[groupOrdinal];
UUID uuid = new UUID(buf.readLong(), buf.readLong());
assertEquals(5, x);
assertEquals(10, y);
assertEquals(Dir.DOWN, dir);
assertEquals(true, moving);
assertEquals(Group.BAD, g);
assertEquals(id, uuid);
}
@Test
void testDecoder() {
EmbeddedChannel ch = new EmbeddedChannel();
UUID id = UUID.randomUUID();
TankJoinMessage message = new TankJoinMessage(5, 10, Dir.DOWN, true, Group.BAD, id);
ch.pipeline()
.addLast(new MessageDecoder());
ByteBuf buf = Unpooled.buffer();
buf.writeInt(MessageType.TankJoin.ordinal());
byte[] bytes = message.toBytes();
buf.writeInt(bytes.length);
buf.writeBytes(bytes);
ch.writeInbound(buf.duplicate());
TankJoinMessage msg = (TankJoinMessage) ch.readInbound();
assertEquals(5, msg.x);
assertEquals(10, msg.y);
assertEquals(Dir.DOWN, msg.dir);
assertEquals(true, msg.moving);
assertEquals(Group.BAD, msg.group);
assertEquals(id, msg.id);
}
}

@ -1,71 +0,0 @@
package com.example.tankbattle.net;
import com.example.tankbattle.Dir;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.*;
class TankStartMovingMessageTest {
@Test
void testEncoder() {
EmbeddedChannel ch = new EmbeddedChannel();
UUID id = UUID.randomUUID();
Message message = new TankDirChangedMessage(id, 5, 10, Dir.LEFT);
ch.pipeline()
.addLast(new MessageEncoder());
ch.writeOutbound(message);
ByteBuf buf = (ByteBuf)ch.readOutbound();
MessageType messageType = MessageType.values()[buf.readInt()];
assertEquals(MessageType.TankDirChanged, messageType);
int length = buf.readInt();
assertEquals(28, length);
UUID uuid = new UUID(buf.readLong(), buf.readLong());
int x = buf.readInt();
int y = buf.readInt();
int dirOrdinal = buf.readInt();
Dir dir = Dir.values()[dirOrdinal];
assertEquals(5, x);
assertEquals(10, y);
assertEquals(Dir.LEFT, dir);
assertEquals(id, uuid);
}
@Test
void testDecoder() {
EmbeddedChannel ch = new EmbeddedChannel();
UUID id = UUID.randomUUID();
TankDirChangedMessage message = new TankDirChangedMessage(id, 5, 10, Dir.LEFT);
ch.pipeline()
.addLast(new MessageDecoder());
ByteBuf buf = Unpooled.buffer();
buf.writeInt(MessageType.TankDirChanged.ordinal());
byte[] bytes = message.toBytes();
buf.writeInt(bytes.length);
buf.writeBytes(bytes);
ch.writeInbound(buf.duplicate());
TankDirChangedMessage msgR = (TankDirChangedMessage)ch.readInbound();
assertEquals(5, msgR.getX());
assertEquals(10, msgR.getY());
assertEquals(Dir.LEFT, msgR.getDir());
assertEquals(id, msgR.getId());
}
}
Loading…
Cancel
Save