Skip to content

Commit

Permalink
Added Mario-esque camera. It is a bit hacky, since it only takes into
Browse files Browse the repository at this point in the history
account the size of the camera box, instead of the camera box's location.
In any case, it's a start. Refs #1.
  • Loading branch information
mdkess committed Apr 13, 2012
1 parent 503df3a commit b12ea5c
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 41 deletions.
3 changes: 2 additions & 1 deletion Platformer2012/src/ca/kess/games/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class Constants {
public static final float AIR_RESISTENCE = 0.9f;
public static final float FRICTION = 0.05f;
public static final int MAX_COLLISIONS = 8;
public static final int ZOOM_FACTOR = 4;
public static final int ZOOM_FACTOR = 3;
public static final float DRAG = 1.7f;
public static final float DUMMY_FRICTION = 0.8f;
public static final float HERO_MAX_FORCE = 100.0f;
Expand All @@ -19,4 +19,5 @@ public class Constants {

public static final String LOG = "mdkess-platformer";
public static final int SKIP_FRAMES = 3;
public static final int TILE_SIZE = 8;
}
56 changes: 56 additions & 0 deletions Platformer2012/src/ca/kess/games/camera/FixedCamera.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package ca.kess.games.camera;

import ca.kess.games.Constants;
import ca.kess.games.entities.GameEntity;
import ca.kess.games.world.WorldLevel;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector2;

public class FixedCamera extends GameCamera {
private GameEntity mGameEntity;

public FixedCamera(OrthographicCamera camera, GameEntity entity) {
super(camera);
mGameEntity = entity;
}

public final GameEntity getTarget() {
return mGameEntity;
}

@Override
public void update() {
Vector2 pos = mGameEntity.getPosition();
getCamera().position.set(pos.x, pos.y, 0);
getCamera().update();

}

@Override
public void render(SpriteBatch b, WorldLevel worldLevel) {
float mx = getCamera().position.x;
float my = getCamera().position.y;
float width = Gdx.graphics.getWidth()/(8*Constants.ZOOM_FACTOR);
float height = Gdx.graphics.getWidth()/(8*Constants.ZOOM_FACTOR);
int x0 = Math.max((int) (mx - width/2), 0);
int x1 = Math.min((int) (1+mx + width/2), worldLevel.getWidth());
int y0 = Math.max((int) (my - height/2), 0);
int y1 = Math.min((int) (my + height/2), worldLevel.getHeight());

worldLevel.render(b, x0, y0, x1, y1);
}

@Override
public void onResize(int width, int height) {
getCamera().setToOrtho(false, width/(Constants.TILE_SIZE*Constants.ZOOM_FACTOR), height/(Constants.TILE_SIZE*Constants.ZOOM_FACTOR));
}

@Override
public Matrix4 getCombined() {
return getCamera().combined;
}
}
40 changes: 40 additions & 0 deletions Platformer2012/src/ca/kess/games/camera/GameCamera.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ca.kess.games.camera;

import ca.kess.games.world.WorldLevel;

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Matrix4;

public abstract class GameCamera {
private final OrthographicCamera mCamera;

protected final OrthographicCamera getCamera() {
return mCamera;
}

public GameCamera(OrthographicCamera camera) {
mCamera = camera;
}

/**
* Do any pre-processing logic for the camera
*/
public abstract void update();

/**
* Get the MVP matrix for the camera
*/
public abstract Matrix4 getCombined();

/**
* Called when the screen is resized/reoriented.
*/
public abstract void onResize(int width, int height);

/**
* Render pandas!
*/
public abstract void render(SpriteBatch b, WorldLevel worldLevel);

}
79 changes: 78 additions & 1 deletion Platformer2012/src/ca/kess/games/camera/MarioCamera.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,82 @@
package ca.kess.games.camera;

public class MarioCamera {
import ca.kess.games.Constants;
import ca.kess.games.entities.GameEntity;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;

public class MarioCamera extends FixedCamera {
/**
* The area of the camera, in screen space
*/
private final Rectangle mArea;
public MarioCamera(OrthographicCamera camera, GameEntity entity, Rectangle area) {
super(camera, entity);
mArea = area;
}

@Override
public void update() {
Vector3 cameraPos = getCamera().position;
Vector2 entityPos = getTarget().getPosition();

float f = Constants.ZOOM_FACTOR * Constants.TILE_SIZE;
//Transform entity position to screen space.
float cameraX = cameraPos.x; //in world space (1 = 1 tile)
float cameraY = cameraPos.y;

//Convert to screen space.
float offsetX = (entityPos.x - cameraPos.x)*f;
float offsetY = (entityPos.y - cameraPos.y)*f;



//Camera is always in the middle of the screen
float mx = Gdx.graphics.getWidth()/2;
float my = Gdx.graphics.getHeight()/2;

Gdx.app.log(Constants.LOG, offsetX + " " + offsetY + " " + mx + " " + my);

if(offsetX > mArea.width/2) {
cameraX += (offsetX - (mArea.width/2))/f;
} else if (offsetX < -mArea.width/2) {
cameraX += (offsetX + (mArea.width/2))/f;
}

if(offsetY > mArea.height/2) {
cameraY += (offsetY - (mArea.height/2))/f;
} else if (offsetY < -mArea.height/2) {
cameraY += (offsetY + (mArea.height/2))/f;
}

//only move the camera if the entity is outside of the area.
/*
if(targetY < mArea.y) {
targetY = mArea.y;
} else if(targetY > mArea.y + mArea.height) {
targetY = mArea.y + mArea.height;
}
if(targetX < mArea.x) {
targetX = mArea.x;
} else if(targetX > mArea.x + mArea.width) {
targetX = mArea.x + mArea.width;
}*/


getCamera().position.set(cameraX, cameraY, 0);
//getCamera().position.set(offsetX, offsetY, 0);
//getCamera().position.set(entityPos.x, entityPos.y, 0);
getCamera().update();
}

@Override
public void onResize(int width, int height) {
super.onResize(width, height);
}

}
36 changes: 13 additions & 23 deletions Platformer2012/src/ca/kess/games/screens/GameScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Random;

import ca.kess.games.Constants;
import ca.kess.games.camera.GameCamera;
import ca.kess.games.camera.MarioCamera;
import ca.kess.games.entities.ChestEntity;
import ca.kess.games.entities.GameEntity;
import ca.kess.games.graphics.GraphicsCache;
Expand All @@ -19,14 +21,14 @@
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;

public class GameScreen extends PlatformerScreen {
private SpriteBatch mSpriteBatch;
private SpriteBatch mDebugSpriteBatch;
private OrthographicCamera mCamera;
private GameCamera mCamera;
private WorldLevel mWorldLevel;
private final GameEntity mHero;
private Random mRandom = new Random();
Expand Down Expand Up @@ -104,8 +106,7 @@ public boolean keyUp(int keycode) {
};


mCamera = new OrthographicCamera(Gdx.graphics.getWidth()/(8*Constants.ZOOM_FACTOR), Gdx.graphics.getHeight()/(8*Constants.ZOOM_FACTOR));
mCamera.position.set(0, 0, 0);


mWorldLevel = new WorldLevel(this, "data/map.png");

Expand All @@ -115,6 +116,9 @@ public boolean keyUp(int keycode) {
InputHandler inputHandler = new InputHandler(mHero);
mHero.setInputHandler(inputHandler);

mCamera = new MarioCamera(new OrthographicCamera(Gdx.graphics.getWidth()/(Constants.TILE_SIZE*Constants.ZOOM_FACTOR), Gdx.graphics.getHeight()/(Constants.TILE_SIZE*Constants.ZOOM_FACTOR)), mHero
, new Rectangle(300, 200, Gdx.graphics.getWidth() - 600, Gdx.graphics.getHeight() - 400));

for(int i = 0; i < 128; i += 16) {
GameEntity obj = mWorldLevel.getGameEntityPool().getGameEntity().initialize(
new Animation(0.5f, GraphicsCache.getObject(mRandom.nextInt(14), mRandom.nextInt(14))), mWorldLevel, 0.5f);
Expand Down Expand Up @@ -268,9 +272,6 @@ private void initGUI() {
mReviveButton.height = size;
}


public OrthographicCamera getCamera() { return mCamera; }

private float mTotalTime = 0.0f;
private float mAccumulator = 0.0f;
@Override
Expand All @@ -293,16 +294,14 @@ public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

Vector2 pos = mHero.getPosition();
mCamera.position.set(pos.x, pos.y, 0);

mCamera.update();

mTotalTime += Gdx.graphics.getDeltaTime();

mSpriteBatch.setProjectionMatrix(mCamera.combined);
mSpriteBatch.setProjectionMatrix(mCamera.getCombined());
mSpriteBatch.begin();
mWorldLevel.render(mSpriteBatch);
mCamera.render(mSpriteBatch, mWorldLevel);
mSpriteBatch.end();

mStage.draw();
Expand All @@ -324,23 +323,14 @@ private void drawDebugInfo() {
mFont.draw(mDebugSpriteBatch, "On Ground: " + mHero.isOnGround(), 10, 320);
mDebugSpriteBatch.end();
}

private void drawUserInterface() {
/*
mGUISpriteBatch.begin();
for(Button button : mButtons) {
button.render(mGUISpriteBatch);
}
mGUISpriteBatch.end();
*/
}


@Override
public void resize(int width, int height) {
Gdx.app.log(Constants.LOG, "GameScreen::resise(" + width + ", " + height + ")");
mStage.setViewport(width, height, true);
initGUI();
mCamera.setToOrtho(false, Gdx.graphics.getWidth()/(8*Constants.ZOOM_FACTOR), Gdx.graphics.getHeight()/(8*Constants.ZOOM_FACTOR));
mCamera.onResize(width, height);

}

@Override
Expand Down
31 changes: 15 additions & 16 deletions Platformer2012/src/ca/kess/games/world/WorldLevel.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Disposable;

public class WorldLevel implements IRenderable, IUpdateable, Disposable {
public class WorldLevel implements IUpdateable, Disposable {
private TileSet mTileSet;
private Tile[][] mTiles;
private GameScreen mGame;
Expand All @@ -46,9 +47,9 @@ public WorldLevel(GameScreen game, String mapLocation) {
mEntitiesToRemove = new LinkedList<GameEntity>();
mTimers = new LinkedList<Timer>();
mFinishedTimers = new LinkedList<Timer>();

mTileSet = new TileSet();

mGame = game;
Pixmap pixmap = new Pixmap(Gdx.files.internal(mapLocation));
mTiles = new Tile[pixmap.getWidth()][pixmap.getHeight()];
Expand Down Expand Up @@ -128,20 +129,11 @@ public void killEntity(GameEntity entity) {

//private Vector2 tmp1 = new Vector2();
//private Vector2 tmp2 = new Vector2();
@Override
public void render(SpriteBatch b) {
public void render(SpriteBatch b, int leftX, int bottomY, int rightX, int topY) {
b.setColor(1,1,1,1);
float mx = mGame.getCamera().position.x;
float my = mGame.getCamera().position.y;
float width = Gdx.graphics.getWidth()/(8*Constants.ZOOM_FACTOR);
float height = Gdx.graphics.getWidth()/(8*Constants.ZOOM_FACTOR);
int x0 = Math.max((int) (mx - width/2), 0);
int x1 = Math.min((int) (1+mx + width/2), mTiles.length);
int y0 = Math.max((int) (my - height/2), 0);
int y1 = Math.min((int) (my + height/2), mTiles[0].length);

for(int x = x0; x < x1; ++x) {
for(int y = y0; y < y1; ++y) {

for(int x = leftX; x < rightX; ++x) {

This comment has been minimized.

Copy link
@mdkess

mdkess Apr 13, 2012

Author Owner

Really we should bake these into some texture instead, and just pick which larger textures to render. I think that would be a lot faster.

for(int y = bottomY; y < topY; ++y) {
mTiles[x][y].render(b, x, y);
}
}
Expand Down Expand Up @@ -307,5 +299,12 @@ public void dispose() {
}
}

public int getWidth() {
return mTiles.length;
}
public int getHeight() {
return mTiles[0].length;
}


}
1 change: 1 addition & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A simple 2D platformer!

0 comments on commit b12ea5c

Please sign in to comment.