Skip to content

Instantly share code, notes, and snippets.

@matyklug18
Created February 28, 2022 03:50
Show Gist options
  • Save matyklug18/b1b3b57f9f6b3ca11865f192e18e9274 to your computer and use it in GitHub Desktop.
Save matyklug18/b1b3b57f9f6b3ca11865f192e18e9274 to your computer and use it in GitHub Desktop.
// vim: set ft=java:
import java.util.*;
class Vector2f {
public float x, y;
public Vector2f(float x, float y) {
this.x = x;
this.y = y;
}
public Vector2f(Vector2f copy) {
this.x = copy.x;
this.y = copy.y;
}
public Vector2f() {
this.x = 0.0f;
this.y = 0.0f;
}
public Vector2f addWith(Vector2f other) {
this.x += other.x;
this.y += other.y;
return this;
}
public Vector2f mulWith(float other) {
this.x *= other;
this.y *= other;
return this;
}
public Vector2f addGet(Vector2f other) {
Vector2f result = new Vector2f(this);
result.x += other.x;
result.y += other.y;
return result;
}
public Vector2f mulGet(float other) {
Vector2f result = new Vector2f(this);
result.x *= other;
result.y *= other;
return result;
}
public float distance(Vector2f other) {
return (float)Math.sqrt((other.y - this.y) * (other.y - this.y) + (other.x - this.x) * (other.x - this.x));
}
//A is negative, B is positive
public boolean within(Vector2f a, Vector2f b) {
if(this.x >= a.x && this.y >= a.y && this.x <= b.x && this.y <= b.y) return true;
else return false;
}
public boolean inRange(Vector2f other, float range) {
return this.distance(other) <= range;
}
@Override
public String toString() {
return "(" + this.x + ", " + this.y + ")";
}
}
class Component {
public String name;
public Component(String name) {
this.name = name;
}
}
class RenderComponent extends Component {
public int clr; // "color" is a reserved keyword in processing because *ofc* it is.
public RenderComponent(int clr) {
super("render");
this.clr = clr;
}
public RenderComponent() {
this(color(255, 255, 255));
}
}
class PositionComponent extends Component {
public Vector2f pos;
public PositionComponent(Vector2f pos) {
super("pos");
this.pos = pos;
}
}
class EnemyComponent extends Component {
public float hp;
public int bulletAmount;
public float timer = 0.0f;
public EnemyComponent(float hp, int bulletAmount) {
super("enemy");
this.hp = hp;
this.bulletAmount = bulletAmount;
}
}
class VelocityComponent extends Component {
public Vector2f vel;
public VelocityComponent() {
this(new Vector2f());
}
public VelocityComponent(Vector2f vel) {
super("vel");
this.vel = vel;
}
}
class BulletComponent extends Component {
public float dmg;
public BulletComponent(float dmg) {
super("bullet");
this.dmg = dmg;
}
}
class PlayerComponent extends Component {
public PlayerComponent() {
super("player");
}
}
class System {
public List<String> inputs = new ArrayList<>();
public void update(Map<String, Component> comps, Entity en) {};
public void prepare() {}
public System(String... inputNames) {
for(String s : inputNames) {
inputs.add(s);
}
}
}
class RenderSystem extends System {
public RenderSystem() {
super("render", "pos");
}
public void update(Map<String, Component> comps, Entity en) {
PositionComponent posC = (PositionComponent)comps.get("pos");
RenderComponent renC = (RenderComponent)comps.get("render");
fill(renC.clr);
ellipse(posC.pos.x-5, posC.pos.y-5, 10, 10);
}
public void prepare() {
clear();
}
}
class VelocitySystem extends System {
public VelocitySystem() {
super("pos", "vel");
}
public void update(Map<String, Component> comps, Entity en) {
PositionComponent posC = (PositionComponent)comps.get("pos");
VelocityComponent velC = (VelocityComponent)comps.get("vel");
posC.pos.addWith(velC.vel.mulGet(delta/1000.0f));
}
}
class BulletSpawnSystem extends System {
private static final float VELOCITY_MUL = 50.0f;
public BulletSpawnSystem() {
super("pos", "enemy", "vel");
}
public void update(Map<String, Component> comps, Entity en) {
EnemyComponent enemC = (EnemyComponent)comps.get("enemy");
VelocityComponent velC = (VelocityComponent)comps.get("vel");
if(enemC.timer >= 0.5f) {
PositionComponent posC = (PositionComponent)comps.get("pos");
for(int i = 0; i < enemC.bulletAmount; i++) {
double a = Math.toRadians(i*(360.0f/((float)enemC.bulletAmount)));
addEnsUp(new Entity(
new BulletComponent(10.0f),
new VelocityComponent(new Vector2f((float)Math.sin(a)*VELOCITY_MUL, (float)Math.cos(a)*VELOCITY_MUL).addWith(velC.vel)),
new PositionComponent(new Vector2f(posC.pos)),
new RenderComponent(color(255,63,63))
));
}
enemC.timer = 0.0f;
}
enemC.timer += delta/1000.0f;
}
}
class BulletClearSystem extends System {
public BulletClearSystem() {
super("pos", "bullet");
}
public void update(Map<String, Component> comps, Entity en) {
PositionComponent posC = (PositionComponent)comps.get("pos");
if(!posC.pos.within(new Vector2f(0.0f,0.0f), new Vector2f(410.0f, 610.0f))) {
remEnsUp(en);
}
}
}
class PlayerControlSystem extends System {
public PlayerControlSystem() {
super("pos", "player");
}
public void update(Map<String, Component> comps, Entity en) {
PositionComponent posC = (PositionComponent)comps.get("pos");
Vector2f dir = new Vector2f();
float speed = 4.0f;
if(keyB == 'w') dir = new Vector2f( 0.0f,-1.0f);
if(keyB == 's') dir = new Vector2f( 0.0f, 1.0f);
if(keyB == 'a') dir = new Vector2f(-1.0f, 0.0f);
if(keyB == 'd') dir = new Vector2f( 1.0f, 0.0f);
if(posC.pos.addGet(dir).within(new Vector2f(5.0f, 5.0f), new Vector2f(400.0f, 600.0f)))
posC.pos.addWith(dir.mulGet(speed));
}
}
class PlayerDeathSystem extends System {
public PlayerDeathSystem() {
super("pos", "player");
}
public void update(Map<String, Component> comps, Entity en) {
PositionComponent posC = (PositionComponent)comps.get("pos");
for(Entity e : ens) {
if(e.comps.containsKey("pos") && (e.comps.containsKey("bullet") || e.comps.containsKey("enemy"))) {
PositionComponent posCE = (PositionComponent)e.comps.get("pos");
if(posCE.pos.inRange(posC.pos, 10.0f)) {
dead = true;
}
}
}
}
}
class Entity {
public Map<String, Component> comps = new HashMap<>();
public Entity(Component... com) {
for(Component c : com) {
if(comps.containsKey(c.name)) {
throw new IllegalStateException("Duplicate component "+c.name);
}
comps.put(c.name, c);
}
}
}
List<Entity> ensUp = new ArrayList<>();
List<Entity> ensUpRem = new ArrayList<>();
List<Entity> ens = new ArrayList<>();
List<System> sys = new ArrayList<>();
char keyB = '\0';
void addSys(System... syss) {
for(System sy : syss) {
sys.add(sy);
}
}
void addEnsUp(Entity... enss) {
for(Entity en : enss) {
ensUp.add(en);
}
}
void remEnsUp(Entity... enss) {
for(Entity en : enss) {
ensUpRem.add(en);
}
}
void addEns(Entity... enss) {
for(Entity en : enss) {
ens.add(en);
}
}
void setup() {
size(400, 600);
clear();
addSys(
new RenderSystem(),
new VelocitySystem(),
new BulletSpawnSystem(),
new BulletClearSystem(),
new PlayerControlSystem(),
new PlayerDeathSystem()
);
addEns(
new Entity(new EnemyComponent(100.0f, 12), new RenderComponent(color(0,255,255)), new PositionComponent(new Vector2f(100, 100)), new VelocityComponent(new Vector2f(0.0f, 100.0f))),
new Entity(new EnemyComponent(100.0f, 12), new RenderComponent(color(0,255,255)), new PositionComponent(new Vector2f(300, 100)), new VelocityComponent(new Vector2f(0.0f, 100.0f))),
new Entity(new PlayerComponent(), new RenderComponent(color(255,255,255)), new PositionComponent(new Vector2f(200, 550)), new VelocityComponent())
);
}
int lastTime = 0;
int delta = 0;
boolean dead = false;
void draw() {
if(dead) return;
delta = millis() - lastTime;
for(System sy : sys) {
sy.prepare();
ensUp.clear();
ensUpRem.clear();
for(Entity en : ens) {
Map<String, Component> com = new HashMap<>();
boolean satisfy = true;
for(String in : sy.inputs) {
if(en.comps.containsKey(in)) {
com.put(in, en.comps.get(in));
} else {
satisfy = false;
}
}
if(satisfy) {
sy.update(com, en);
}
}
for(Entity e : ensUpRem) {
ens.remove(e);
}
ens.addAll(ensUp);
}
lastTime = millis();
}
void keyPressed() {
keyB = key;
}
void keyReleased() {
keyB = '\0';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment