Compare commits

..

3 Commits

Author SHA1 Message Date
kn5886348135 76f7f49812 添加墙和碰撞策略
3 years ago
kn5886348135 c3b59f519e 门面模式操作游戏对象,责任链模式检测碰撞
3 years ago
kn5886348135 2860e1a336 移动包
3 years ago

@ -3,14 +3,13 @@ package com.example.tankbattle;
import java.awt.Graphics;
import java.awt.Rectangle;
public class Bullet {
public class Bullet extends GameObject{
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;
@ -29,7 +28,7 @@ public class Bullet {
rect.width = WIDTH;
rect.height = HEIGHT;
gm.bullets.add(this);
gm.add(this);
}
public Group getGroup() {
@ -40,9 +39,18 @@ public class Bullet {
this.group = group;
}
public Rectangle getRect() {
return rect;
}
public void setRect(Rectangle rect) {
this.rect = rect;
}
@Override
public void paint(Graphics g) {
if (!living) {
gm.bullets.remove(this);
gm.remove(this);
}
switch (dir) {
case LEFT:
@ -89,18 +97,20 @@ public class Bullet {
if (x < 0 || y < 0 || x > TankFrame.GAME_WIDTH || y > TankFrame.GAME_HEIGHT) living = false;
}
public void collideWith(Tank tank){
if (this.group == tank.getGroup()) return;
public boolean collideWith(Tank tank){
if (this.group == tank.getGroup()) return false;
if (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;
gm.explodes.add(new Explode(eX, eY, gm));
gm.add(new Explode(eX, eY, gm));
return true;
}
return false;
}
private void die() {
public void die() {
this.living = false;
}
}

@ -2,12 +2,10 @@ package com.example.tankbattle;
import java.awt.Graphics;
public class Explode {
public class Explode extends GameObject {
public static int WIDTH = ResourceMgr.explodes[0].getWidth();
public static int HEIGHT = ResourceMgr.explodes[0].getHeight();
private int x, y;
GameModel gm = null;
private int step = 0;
@ -20,12 +18,13 @@ public class Explode {
new Thread(() -> new Audio("audio/explode.wav").play()).start();
}
@Override
public void paint(Graphics g) {
g.drawImage(ResourceMgr.explodes[step++], x, y, null);
if (step >= ResourceMgr.explodes.length)
gm.explodes.remove(this);
gm.remove(this);
}
}

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

@ -1,5 +1,10 @@
package com.example.tankbattle;
import com.example.tankbattle.cor.BulletTankCollider;
import com.example.tankbattle.cor.Collider;
import com.example.tankbattle.cor.ColliderChain;
import com.example.tankbattle.cor.TankTankCollider;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
@ -11,14 +16,30 @@ public class GameModel {
List<Bullet> bullets = new ArrayList<>();
List<Tank> tanks = new ArrayList<>();
List<Explode> explodes = new ArrayList<>();
ColliderChain chain = new ColliderChain();
List<GameObject> objects = new ArrayList<>();
public GameModel() {
int initTankCount = Integer.valueOf(PropertyMgr.get("initTankCount"));
// 初始化敌方坦克
for (int i = 0; i < initTankCount; i++) {
tanks.add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, this));
add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, this));
}
add(new Wall(150, 150, 200, 50));
add(new Wall(550, 150, 200, 50));
add(new Wall(500, 300, 200, 50));
add(new Wall(300, 500, 50, 200));
}
public void add(GameObject go) {
this.objects.add(go);
}
public void remove(GameObject go) {
this.objects.remove(go);
}
public void paint(Graphics g) {
@ -30,22 +51,25 @@ public class GameModel {
g.setColor(c);
myTank.paint(g);
for (int i = 0; i < bullets.size(); i++) {
bullets.get(i).paint(g);
}
for (int i = 0; i < tanks.size(); i++) {
tanks.get(i).paint(g);
for (int i = 0; i < objects.size(); i++) {
objects.get(i).paint(g);
}
for (int i = 0; i < explodes.size(); i++) {
explodes.get(i).paint(g);
// 互相碰撞逻辑
for (int i = 0; i < objects.size(); i++) {
for (int j = i + 1; j < objects.size(); j++) {
GameObject o1 = objects.get(i);
GameObject o2 = objects.get(j);
// collider.collide(o1, o2);
// collider2.collide(o1, o2);
chain.collide(o1, o2);
}
}
for (int i = 0; i < bullets.size(); i++) {
for (int j = 0; j < tanks.size(); j++)
bullets.get(i).collideWith(tanks.get(j));
}
// for (int i = 0; i < bullets.size(); i++) {
// for (int j = 0; j < tanks.size(); j++)
// bullets.get(i).collideWith(tanks.get(j));
// }
// for (Iterator<Bullet> it = bullets.iterator(); it.hasNext()) {
// Bullet b = it.next();

@ -0,0 +1,10 @@
package com.example.tankbattle;
import java.awt.Graphics;
public abstract class GameObject {
public int x;
public int y;
public abstract void paint(Graphics g);
}

@ -1,9 +1,12 @@
package com.example.tankbattle;
import com.example.tankbattle.strategy.DefaultFireStrategy;
import com.example.tankbattle.strategy.FireStrategy;
import java.awt.*;
import java.util.Random;
public class Tank {
public class Tank extends GameObject{
private static final int SPEED = 2;
public static int WIDTH = ResourceMgr.goodTankU.getWidth();
@ -13,18 +16,18 @@ public class Tank {
private Random random = new Random();
int x,y;
Dir dir = Dir.DOWN;
public Dir dir = Dir.DOWN;
private boolean moving = true;
private boolean living = true;
Group group = Group.BAD;
public Group group = Group.BAD;
int oldX, oldY;
FireStrategy fs;
GameModel gm;
public GameModel gm;
public Tank(int x, int y, Dir dir, Group group, GameModel gm) {
super();
@ -53,6 +56,10 @@ public class Tank {
}
}
public Rectangle getRect() {
return rect;
}
public void fire(){
fs.fire(this);
}
@ -82,6 +89,9 @@ public class Tank {
}
private void move() {
oldX=x;
oldY=y;
if (!moving) return;
switch (dir) {
case LEFT:
@ -123,8 +133,10 @@ public class Tank {
this.dir = Dir.values()[random.nextInt(4)];
}
@Override
public void paint(Graphics g) {
if (!living) gm.tanks.remove(this);
if (!living) gm.remove(this);
switch (dir) {
case LEFT:
g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankL : ResourceMgr.badTankL, x, y, null);
@ -163,4 +175,14 @@ public class Tank {
public void die() {
this.living = false;
}
public void stop() {
this.moving = false;
}
public void back() {
x = oldX;
y = oldY;
}
}

@ -0,0 +1,52 @@
package com.example.tankbattle;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
public class Wall extends GameObject{
int w, h;
public Rectangle rect;
public int getW() {
return w;
}
public void setW(int w) {
this.w = w;
}
public int getH() {
return h;
}
public void setH(int h) {
this.h = h;
}
public Rectangle getRect() {
return rect;
}
public void setRect(Rectangle rect) {
this.rect = rect;
}
public Wall(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.rect = new Rectangle(x, y, w, h);
}
@Override
public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.GRAY);
g.fillRect(x, y, w, h);
g.setColor(c);
}
}

@ -0,0 +1,26 @@
package com.example.tankbattle.cor;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.GameObject;
import com.example.tankbattle.Tank;
public class BulletTankCollider implements Collider {
@Override
public boolean collide(GameObject o1, GameObject o2) {
if (o1 instanceof Bullet && o2 instanceof Tank) {
Bullet bullet = (Bullet) o1;
Tank t = (Tank) o2;
if (bullet.collideWith(t)){
return false;
} else {
return true;
}
} else if (o1 instanceof Tank && o2 instanceof Bullet) {
return collide(o2, o1);
} else {
return true;
}
}
}

@ -0,0 +1,25 @@
package com.example.tankbattle.cor;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.GameObject;
import com.example.tankbattle.Wall;
public class BulletWallCollider implements Collider {
@Override
public boolean collide(GameObject o1, GameObject o2) {
if (o1 instanceof Bullet && o2 instanceof Wall) {
Bullet bullet = (Bullet) o1;
Wall wall = (Wall) o2;
if (bullet.getRect().intersects(wall.getRect())) {
System.out.println("bullet die");
bullet.die();
} else if (o1 instanceof Wall && o2 instanceof Bullet) {
return collide(o2, o1);
}
} else {
System.out.println(o1.getClass().getName() + " " + o2.getClass().getName());
}
return true;
}
}

@ -0,0 +1,7 @@
package com.example.tankbattle.cor;
import com.example.tankbattle.GameObject;
public interface Collider {
boolean collide(GameObject o1, GameObject o2);
}

@ -0,0 +1,32 @@
package com.example.tankbattle.cor;
import com.example.tankbattle.GameObject;
import java.util.LinkedList;
import java.util.List;
public class ColliderChain implements Collider {
private List<Collider> colliders = new LinkedList<>();
public ColliderChain() {
add(new BulletTankCollider());
add(new TankTankCollider());
add(new BulletWallCollider());
add(new TankWallCollider());
}
public void add(Collider c) {
colliders.add(c);
}
@Override
public boolean collide(GameObject o1, GameObject o2) {
for (int i = 0; i < colliders.size(); i++) {
if (!colliders.get(i).collide(o1, o2)) {
return false;
}
}
return true;
}
}

@ -0,0 +1,23 @@
package com.example.tankbattle.cor;
import com.example.tankbattle.GameObject;
import com.example.tankbattle.Tank;
public class TankTankCollider implements Collider {
@Override
public boolean collide(GameObject o1, GameObject o2) {
if (o1 instanceof Tank && o2 instanceof Tank) {
Tank t1 = (Tank) o1;
Tank t2 = (Tank) o2;
if ( t1.getRect().intersects(t2.getRect())){
// t1.stop();
// t2.stop();
t1.back();
t2.back();
}
}
return true;
}
}

@ -0,0 +1,23 @@
package com.example.tankbattle.cor;
import com.example.tankbattle.GameObject;
import com.example.tankbattle.Tank;
import com.example.tankbattle.Wall;
public class TankWallCollider implements Collider {
@Override
public boolean collide(GameObject o1, GameObject o2) {
if (o1 instanceof Tank && o2 instanceof Wall) {
Tank tank = (Tank) o1;
Wall wall = (Wall) o2;
if (tank.getRect().intersects(wall.getRect())) {
tank.back();
} else if (o1 instanceof Wall && o2 instanceof Tank) {
return collide(o2, o1);
}
}
return true;
}
}

@ -1,4 +1,4 @@
package com.example.tankbattle.strategy;
package com.example.tankbattle.demo;
public class Cat implements CustomComparable<Cat> {

@ -1,4 +1,4 @@
package com.example.tankbattle.strategy;
package com.example.tankbattle.demo;
public interface CustomComparable<T> {
int compareTo(T o);

@ -1,4 +1,4 @@
package com.example.tankbattle.strategy;
package com.example.tankbattle.demo;
public interface CustomComparator<T> {
int compare(T o1, T o2);

@ -1,4 +1,4 @@
package com.example.tankbattle.strategy;
package com.example.tankbattle.demo;
public class Dog implements CustomComparable<Dog> {

@ -1,4 +1,4 @@
package com.example.tankbattle.strategy;
package com.example.tankbattle.demo;
public class DogComparator implements CustomComparator<Dog> {

@ -1,4 +1,4 @@
package com.example.tankbattle.strategy;
package com.example.tankbattle.demo;
import java.util.Arrays;

@ -1,4 +1,4 @@
package com.example.tankbattle.strategy;
package com.example.tankbattle.demo;
public class Sorter<T> {

@ -1,4 +1,9 @@
package com.example.tankbattle;
package com.example.tankbattle.strategy;
import com.example.tankbattle.Audio;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.Group;
import com.example.tankbattle.Tank;
public class DefaultFireStrategy implements FireStrategy{

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

@ -1,4 +1,10 @@
package com.example.tankbattle;
package com.example.tankbattle.strategy;
import com.example.tankbattle.Audio;
import com.example.tankbattle.Bullet;
import com.example.tankbattle.Dir;
import com.example.tankbattle.Group;
import com.example.tankbattle.Tank;
public class FourDirFireStrategy implements FireStrategy{

@ -5,5 +5,7 @@ bulletSpeed=10
gameWidth=1080
gameHeight=720
#fireStrategy
goodFS=com.example.tankbattle.FourDirFireStrategy
badFS=com.example.tankbattle.DefaultFireStrategy
goodFS=com.example.tankbattle.strategy.FourDirFireStrategy
badFS=com.example.tankbattle.strategy.DefaultFireStrategy
#colliders
colliders=com.example.tankbattle.cor.BulletTankCollider,com.example.tankbattle.cor.TankTankCollider
Loading…
Cancel
Save