Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asteroids #531

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 38 additions & 14 deletions engine/src/main/java/org/destinationsol/SolApplication.java
Expand Up @@ -30,12 +30,17 @@
import org.destinationsol.entitysystem.EntitySystemManager;
import org.destinationsol.entitysystem.SerialisationManager;
import org.destinationsol.game.DebugOptions;
import org.destinationsol.game.FactionInfo;
import org.destinationsol.game.ObjectManager;
import org.destinationsol.game.SaveManager;
import org.destinationsol.game.SolGame;
import org.destinationsol.game.WorldConfig;
import org.destinationsol.game.console.adapter.ParameterAdapterManager;
import org.destinationsol.game.context.Context;
import org.destinationsol.game.context.internal.ContextImpl;
import org.destinationsol.game.item.ItemManager;
import org.destinationsol.game.item.LootBuilder;
import org.destinationsol.location.components.Position;
import org.destinationsol.menu.MenuScreens;
import org.destinationsol.menu.background.MenuBackgroundManager;
import org.destinationsol.modules.ModuleManager;
Expand All @@ -51,6 +56,7 @@
import org.slf4j.LoggerFactory;
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.gestalt.entitysystem.component.management.ComponentManager;
import org.terasology.gestalt.entitysystem.entity.EntityRef;
import org.terasology.gestalt.module.sandbox.API;

import java.io.PrintWriter;
Expand Down Expand Up @@ -92,6 +98,8 @@ public class SolApplication implements ApplicationListener {
private float timeAccumulator = 0;
private boolean isMobile;

private ComponentManager componentManager;

// TODO: Make this non-static.
private static Set<ResizeSubscriber> resizeSubscribers;

Expand All @@ -114,23 +122,12 @@ public void create() {
}
options = new GameOptions(isMobile(), null);

ComponentManager componentManager = new ComponentManager();
componentManager = new ComponentManager();
AssetHelper helper = new AssetHelper();
helper.init(moduleManager.getEnvironment(), componentManager, isMobile);
Assets.initialize(helper);
entitySystemManager = new EntitySystemManager(moduleManager.getEnvironment(), componentManager, context);

context.put(ComponentSystemManager.class, new ComponentSystemManager(moduleManager.getEnvironment(), context));

// Big, fat, ugly HACK to get a working classloader
// Serialisation and thus a classloader is not needed when there are no components
Iterator<Class<? extends Component>> componentClasses =
moduleManager.getEnvironment().getSubtypesOf(Component.class).iterator();
SerialisationManager serialisationManager = new SerialisationManager(
SaveManager.getResourcePath("entity_store.dat"), entitySystemManager.getEntityManager(),
componentClasses.hasNext() ? componentClasses.next().getClassLoader() : null);
context.put(SerialisationManager.class, serialisationManager);

logger.info("\n\n ------------------------------------------------------------ \n");
moduleManager.printAvailableModules();

Expand Down Expand Up @@ -258,17 +255,44 @@ private void draw() {
}

public void play(boolean tut, String shipName, boolean isNewGame, WorldConfig worldConfig) {

context.get(ComponentSystemManager.class).preBegin();
solGame = new SolGame(shipName, tut, isNewGame, commonDrawer, context, worldConfig);
context.put(SolGame.class, solGame);

context.put(LootBuilder.class, solGame.getLootBuilder());
context.put(ItemManager.class, solGame.getItemMan());
context.put(ObjectManager.class, solGame.getObjectManager());

entitySystemManager = new EntitySystemManager(moduleManager.getEnvironment(), componentManager, context);


// Big, fat, ugly HACK to get a working classloader
// Serialisation and thus a classloader is not needed when there are no components
Iterator<Class<? extends Component>> componentClasses =
moduleManager.getEnvironment().getSubtypesOf(Component.class).iterator();
SerialisationManager serialisationManager = new SerialisationManager(
SaveManager.getResourcePath("entity_store.dat"), entitySystemManager.getEntityManager(),
componentClasses.hasNext() ? componentClasses.next().getClassLoader() : null);
context.put(SerialisationManager.class, serialisationManager);

if (!isNewGame) {
try {
context.get(SerialisationManager.class).deserialise();
} catch (Exception e) {
e.printStackTrace();
}
}
context.get(ComponentSystemManager.class).preBegin();
solGame = new SolGame(shipName, tut, isNewGame, commonDrawer, context, worldConfig);

factionDisplay = new FactionDisplay(solGame.getCam());
inputManager.setScreen(this, solGame.getScreens().mainGameScreen);

EntityRef entity = entitySystemManager.getEntityManager().createEntity(Assets.getPrefab("core:asteroid"));
Position position = entity.getComponent(Position.class).get();
position.position = solGame.getHero().getPosition().cpy();
position.position.x += 1;
position.position.y += 3;
entity.setComponent(position);
}

public SolInputManager getInputManager() {
Expand Down
@@ -0,0 +1,25 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.asteroids.components;

import org.terasology.gestalt.entitysystem.component.Component;

public class Asteroid implements Component<Asteroid> {
@Override
public void copy(Asteroid other) {

}
}
@@ -0,0 +1,75 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.asteroids.systems;

import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.World;
import org.destinationsol.assets.Assets;
import org.destinationsol.asteroids.components.Asteroid;
import org.destinationsol.body.events.BodyCreatedEvent;
import org.destinationsol.body.events.BodyUpdateEvent;
import org.destinationsol.body.events.GenerateBodyEvent;
import org.destinationsol.common.In;
import org.destinationsol.common.SolRandom;
import org.destinationsol.entitysystem.EntitySystemManager;
import org.destinationsol.entitysystem.EventReceiver;
import org.destinationsol.game.CollisionMeshLoader;
import org.destinationsol.game.drawables.Drawable;
import org.destinationsol.game.drawables.DrawableLevel;
import org.destinationsol.location.components.Angle;
import org.destinationsol.location.components.Position;
import org.destinationsol.size.components.Size;
import org.terasology.gestalt.entitysystem.entity.EntityRef;
import org.terasology.gestalt.entitysystem.event.EventResult;
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;

import java.util.ArrayList;
import java.util.List;

public class AsteroidBodyCreationSystem implements EventReceiver {

private static final float DENSITY = 10f;

@In
private EntitySystemManager entitySystemManager;

//TODO
@In
private World world;

private final CollisionMeshLoader collisionMeshLoader = new CollisionMeshLoader("engine:asteroids");
private final List<TextureAtlas.AtlasRegion> textures = Assets.listTexturesMatching("engine:asteroid_.*");

@ReceiveEvent(components = {Asteroid.class, Size.class, Position.class, Angle.class})
public EventResult onGenerateBody(GenerateBodyEvent event, EntityRef entity) {

TextureAtlas.AtlasRegion texture = SolRandom.randomElement(textures);
float size = entity.getComponent(Size.class).get().size;
Vector2 position = entity.getComponent(Position.class).get().position;
float angle = entity.getComponent(Angle.class).get().getAngle();

ArrayList<Drawable> drawables = new ArrayList<>();

Body body = collisionMeshLoader.getBodyAndSprite(world, texture, size, BodyDef.BodyType.DynamicBody, position, angle, drawables, DENSITY, DrawableLevel.BODIES);

entitySystemManager.sendEvent(new BodyCreatedEvent(body), entity);

return EventResult.CONTINUE;
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.asteroids.systems;

import org.destinationsol.asteroids.components.Asteroid;
import org.destinationsol.body.components.BodyLinked;
import org.destinationsol.common.In;
import org.destinationsol.entitysystem.EntitySystemManager;
import org.destinationsol.entitysystem.EventReceiver;
import org.destinationsol.force.events.ImpulseEvent;
import org.destinationsol.health.components.Health;
import org.destinationsol.health.events.DamageEvent;
import org.terasology.gestalt.entitysystem.entity.EntityRef;
import org.terasology.gestalt.entitysystem.event.EventResult;
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;

public class AsteroidImpulseHandler implements EventReceiver {

private static final float DUR = .5f;

@In
private EntitySystemManager entitySystemManager;

@ReceiveEvent(components = {Asteroid.class, Health.class, BodyLinked.class})
public EventResult onImpulse(ImpulseEvent event, EntityRef entity){

//TODO get the mass from the body
float mass = 1;

float damage = event.getMagnitude() / mass / DUR;
entitySystemManager.sendEvent(new DamageEvent((int) damage), entity);

return EventResult.CONTINUE;
}
}
Expand Up @@ -17,6 +17,7 @@

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Contact;
import org.terasology.gestalt.entitysystem.event.Event;

/**
* Event that represents the magnitude of a sudden, instantaneous force applied to an entity, like the impact of a
Expand All @@ -26,7 +27,7 @@
* This does not represent anything that is an application of continuous force, like gravity. That type of occurrence
* is handled by {@link ForceEvent}.
*/
public class ImpulseEvent {
public class ImpulseEvent implements Event {

private Vector2 contactPosition;
private float magnitude;
Expand Down
Expand Up @@ -20,10 +20,20 @@
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.Manifold;
import org.destinationsol.common.Immutable;
import org.destinationsol.common.In;
import org.destinationsol.common.SolMath;
import org.destinationsol.entitysystem.EntitySystemManager;
import org.destinationsol.force.events.ContactEvent;
import org.destinationsol.force.events.ImpulseEvent;
import org.destinationsol.game.projectile.Projectile;
import org.terasology.gestalt.entitysystem.entity.EntityRef;

public class SolContactListener implements ContactListener {

@In
private EntitySystemManager entitySystemManager;

private final SolGame myGame;

public SolContactListener(SolGame game) {
Expand Down Expand Up @@ -55,21 +65,46 @@ public void preSolve(Contact contact, Manifold oldManifold) {

@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
SolObject soa = (SolObject) contact.getFixtureA().getBody().getUserData();
SolObject sob = (SolObject) contact.getFixtureB().getBody().getUserData();
if (soa instanceof Projectile && ((Projectile) soa).getConfig().density <= 0) {
return;

Object dataA = contact.getFixtureA().getBody().getUserData();
Object dataB = contact.getFixtureB().getBody().getUserData();

Vector2 collPos = contact.getWorldManifold().getPoints()[0];
float absImpulse = calcAbsImpulse(impulse);

if (dataA instanceof EntityRef) {
entitySystemManager.sendEvent(new ImpulseEvent(collPos, absImpulse), (EntityRef) dataA);
}

if (dataB instanceof EntityRef) {
entitySystemManager.sendEvent(new ImpulseEvent(collPos, absImpulse), (EntityRef) dataB);
}
if (sob instanceof Projectile && ((Projectile) sob).getConfig().density <= 0) {

if (dataA instanceof EntityRef && dataB instanceof EntityRef) {
EntityRef entityA = (EntityRef) dataA;
EntityRef entityB = (EntityRef) dataB;
entitySystemManager.sendEvent(new ContactEvent(entityB, contact), entityA);
entitySystemManager.sendEvent(new ContactEvent(entityA, contact), entityB);
return;
}

float absImpulse = calcAbsImpulse(impulse);
Vector2 collPos = contact.getWorldManifold().getPoints()[0];
soa.handleContact(sob, absImpulse, myGame, collPos);
sob.handleContact(soa, absImpulse, myGame, collPos);
myGame.getSpecialSounds().playColl(myGame, absImpulse, soa, collPos);
myGame.getSpecialSounds().playColl(myGame, absImpulse, sob, collPos);
if (dataA instanceof SolObject && dataB instanceof SolObject) {
SolObject soa = (SolObject) contact.getFixtureA().getBody().getUserData();
SolObject sob = (SolObject) contact.getFixtureB().getBody().getUserData();
if (soa instanceof Projectile && ((Projectile) soa).getConfig().density <= 0) {
return;
}
if (sob instanceof Projectile && ((Projectile) sob).getConfig().density <= 0) {
return;
}

soa.handleContact(sob, absImpulse, myGame, collPos);
sob.handleContact(soa, absImpulse, myGame, collPos);
myGame.getSpecialSounds().playColl(myGame, absImpulse, soa, collPos);
myGame.getSpecialSounds().playColl(myGame, absImpulse, sob, collPos);
}

//TODO handle contact between an entity and a SolObject
}

private float calcAbsImpulse(ContactImpulse impulse) {
Expand Down
2 changes: 2 additions & 0 deletions engine/src/main/java/org/destinationsol/game/SolGame.java
Expand Up @@ -60,6 +60,7 @@
import org.destinationsol.ui.TutorialManager;
import org.destinationsol.ui.UiDrawer;
import org.destinationsol.ui.Waypoint;
import org.destinationsol.util.InjectionHelper;
import org.terasology.gestalt.entitysystem.entity.EntityRef;

import java.util.ArrayList;
Expand Down Expand Up @@ -139,6 +140,7 @@ public SolGame(String shipName, boolean isTutorial, boolean isNewGame, CommonDra
SolNames solNames = new SolNames();
planetManager = new PlanetManager(hullConfigManager, gameColors, itemManager);
SolContactListener contactListener = new SolContactListener(this);
InjectionHelper.inject(contactListener, context);
factionManager = new FactionManager();
objectManager = new ObjectManager(contactListener, factionManager);
gridDrawer = new GridDrawer();
Expand Down
@@ -0,0 +1,29 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.loot.components;

import org.destinationsol.game.item.Loot;
import org.terasology.gestalt.entitysystem.component.Component;

/**
* Indicates that when the entity is destroyed, one or more {@link Loot} objects should be created.
*/
public class DropsLootOnDeath implements Component<DropsLootOnDeath> {
@Override
public void copy(DropsLootOnDeath other) {

}
}