Mercurial > projects > openmelee
view melee/melee.d @ 22:4fce5596d1f6
ai work
author | zzzzrrr <mason.green@gmail.com> |
---|---|
date | Thu, 26 Mar 2009 16:56:30 -0400 |
parents | cad384ad349e |
children | e79347dd38a3 |
line wrap: on
line source
/* * Copyright (c) 2009, Mason Green (zzzzrrr) * http://www.dsource.org/projects/openmelee * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the polygonal nor the names of its contributors may be * used to endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ module openmelee.melee.melee; import tango.io.Stdout; version(distrib) import tango.io.vfs.ZipFolder; import tango.time.StopWatch; import fc = tango.text.convert.Float : toString; import tango.util.log.Trace; import xf.core.JobHub; import xf.hybrid.Hybrid; import xf.hybrid.backend.GL; import blaze.common.bzMath : bzVec2; import blaze.bzWorld : bzWorld; import blaze.collision.bzCollision : bzAABB; import openmelee.melee.boundaryListener; import openmelee.melee.contactListener; import openmelee.render.render; import openmelee.ai.ai : AI; import openmelee.ai.human : Human; import openmelee.ships.urQuan : UrQuan; import openmelee.ships.orz : Orz; import openmelee.ships.planet : Planet; import openmelee.ships.asteroids : Asteroid; const ITERS_PER_SECOND = 100; const k_maxContactPoints = 100; // Melee settings struct Settings { float hz = 60; int velocityIterations = 3; int positionIterations = 1; bool drawShapes = true; bool drawJoints = true; bool drawControllers; bool drawCoreShapes; bool drawAABBs; bool drawOBBs; bool drawPairs; bool drawContactPoints; bool drawContactNormals; bool drawContactForces; bool drawFrictionForces; bool drawCOMs; bool drawStats; bool enableWarmStarting; bool enableTOI; } struct ContactPoint { bzShape shape1; bzShape shape2; bzVec2 normal; bzVec2 position; bzVec2 velocity; bzContactID id; //ContactState state; } class Melee { Settings settings; float timeStep; const bzVec2 gravity = bzVec2(0.0f, 0.0f); bool allowSleep; Render draw; AI ai; Human human; Ship ship1; Ship ship2; Planet planet; bool running; StopWatch timer; bzAABB worldAABB; bzWorld world; bzBoundaryListener m_boundaryListener; bzContactListener m_contactListener; ContactPoint[k_maxContactPoints] points; int pointCount; this() { } void init() { timeStep = settings.hz > 0.0f ? 1.0f / settings.hz : 0.0f; version(distrib) gui.vfs.mount(new ZipFolder("./gui.zip")); scope cfg = loadHybridConfig("./gui.cfg"); scope renderer = new Renderer; m_boundaryListener = new BoundaryListener(this); m_contactListener = new ContactListener(this); initWorld(); running = true; draw = new Render(world, ship1, ship2, settings); human = new Human(ship1); ai = new AI(ship1, world); gui.begin(cfg).retained; gui.push(`main`); GLViewport(`glview`).renderingHandler(&draw.draw) .addHandler(&human.onClick) .addHandler(&human.onMove) .addHandler(&human.onKey) .addHandler(&human.onDT) .addHandler(&human.onMouseEnter) .addHandler(&human.onMouseLeave) .grabKeyboardFocus; gui.pop(); gui.immediate.end; jobHub.addRepeatableJob( { // Update physics world.step(timeStep, settings.velocityIterations, settings.positionIterations); }, ITERS_PER_SECOND); jobHub.addPreFrameJob( { // Update AI ai.move(ship2); }); jobHub.addPostFrameJob( { // Limit velocity ship1.limitVelocity(); ship2.limitVelocity(); ship1.updateState(); ship2.updateState(); gui.begin(cfg); gui.push(`main`); if (gui().getProperty!(bool)("frame.closeClicked")) { running = false; } if(human.thrust) { ship1.thrust(); } gui().setProperty!(bool)("showCursor", true); gui.pop(); gui.end; gui.render(renderer); }); while (running && !human.quit) { float delta = timer.stop; timer.start; jobHub.update(delta); } } void initWorld() { // Define world boundaries worldAABB.lowerBound.set(-100.0f, -150.0f); worldAABB.upperBound.set(100.0f, 150.0f); world = new bzWorld(worldAABB, gravity, allowSleep); world.boundaryListener = m_boundaryListener; world.contactListener = m_contactListener; ship1 = new UrQuan(world); ship2 = new Orz(world); ship2.rBody.angle = 3.14159265/4; planet = new Planet(world); //auto asteroids = new Asteroid(world); } void boundaryViolated(bzBody rBody) { float x,y; if(rBody.position.x > worldAABB.upperBound.x) { x = worldAABB.lowerBound.x + 5; rBody.position = bzVec2(x, rBody.position.y); } else if (rBody.position.x < worldAABB.lowerBound.x) { x = worldAABB.upperBound.x - 5; rBody.position = bzVec2(x, rBody.position.y); } else if (rBody.position.y > worldAABB.upperBound.y) { y = worldAABB.lowerBound.y + 5; rBody.position = bzVec2(rBody.position.x, y); } else if(rBody.position.y < worldAABB.lowerBound.y) { y = worldAABB.upperBound.y - 5; rBody.position = bzVec2(rBody.position.x, y); } } }