/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.KPy7eW-ovzS/rev.8622
*
* authors:
* Dillon Hayford
* stefkeB
* Michael Schroder
* Thomas Van Bouwel
* Jose Hernandez
*
* guobing
* Alex Graveley
*
* Mark Webster
*
* Steren
* open architecture open design
* Ali Jaya Meilio
*
*
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
//Eventua
//Written by Michael Schroder
public static final string MAP1 = "/static/uploaded_resources/p.218/map1.png";
/* @pjs preload="/static/uploaded_resources/p.218/map1.png"; */
public static final int TILE_NONE = 0;
public static final int TILE_SOLID = 1;
public static final double TILE_SIZE = .05;
public class Tile{
public int type;
public Tile(){
type=TILE_NONE;
}
public void draw(int x, int y){
if(type == TILE_SOLID){
stroke(255, 255, 255, 100);
fill(0, 120, 0, 255);
strokeWeight(6);
rect(x, y, TILE_SIZE*height, TILE_SIZE*height);
}
}
}
public class Level{
private Tile tiles[];
private double w;
private double h;
private double offx;
private double offy;
public Level(int W, int H){
w=W;
h=H;
offx=0;
offy=0;
tiles = new Tile[w*h];
for(int i=0; i<w*h; i++){
tiles[i] = new Tile();
}
}
public Tile getTile(int index){
if(index < w*h)
return tiles[index];
Tile temp = new Tile();
return temp;
}
public Tile getTile(double x, double y){
y = (int)((double)(y)/(TILE_SIZE)+.001);
x = (int)((double)(x)/(TILE_SIZE)+.001);
if(x < w && x >= 0 && y < h && y >= 0){
return tiles[y*w+x];
}
Tile temp = new Tile();
return temp;
}
public bool setTile(int index, Tile tile){
if(index < w*h && index >= 0){
tiles[index] = tile;
return true;
}
return false;
}
public bool setTile(int x, int y, Tile tile){
if(x < w && y < h){
tiles[(int)((double)(offy+y)/(TILE_SIZE))*w+(int)((double)(offx+x)/(TILE_SIZE))] = tile;
return true;
}
return false;
}
public void Draw(){
for(int x=offx; x<=w/h+offx+TILE_SIZE; x+=TILE_SIZE){
for(int y=offy; y<1+offy+TILE_SIZE; y+=TILE_SIZE){
//println(x);
getTile(x,y).draw(((int)((double)(x)/(TILE_SIZE)+.001)*TILE_SIZE-offx)*height,((int)((double)(y)/(TILE_SIZE)+.001)*TILE_SIZE-offy)*height);
}
}
}
public double getOffsetX(){
return offx;
}
public double getOffsetY(){
return offy;
}
public void setOffsetX(double off){
offx=off;
}
public void setOffsetY(double off){
offy=off;
}
public double getWidth(){
return w;
}
public double getHeight(){
return h;
}
public boolean isOnScreen(double x, double y, double width, double height){
if(x+width < offx || x > offx+w || y+height < offy || y > offy+h) return false;
return true;
}
}
public class IntVec{
private int[] vals;
int max, cur;
public IntVec(){
vals = new int[1];
max=1;
cur=0;
}
public void add(int val){
if(cur==max){
int[] nvals = new int[max*2];
for(int i=0; i<max; i++){
nvals[i] = vals[i];
}
max = max*2;
vals = nvals;
}
vals[cur++] = val;
}
public void remove(int index){
vals[index] = vals[--cur];
}
public int getVal(int index){
return vals[index];
}
public int size(){
return cur;
}
}
int numSteps;
boolean Keys[256] = {0};
public class Mover{
protected double x;
protected double y;
protected double w;
protected double h;
protected double xspeed;
protected double yspeed;
protected double friction;
protected double gravity;
protected boolean onGround;
protected boolean moverCollisions;
protected boolean levelCollisions;
public Mover(){
x=.4;
y=.5;
w=.04;
h=.05;
xspeed=0;
yspeed=0;
friction = 1;
gravity = 0;
onGround=false;
moverCollisions=false;
levelCollisions=false;
}
protected void checkLevelCollisions(Level l){
onGround=false;
//Up&Down Collision Checking
if(yspeed > 0 && (l.getTile(x+w/2,y+h).type==TILE_SOLID || (l.getTile(x+w*.01,y+h).type==TILE_SOLID && l.getTile(x,y+h/2).type!=TILE_SOLID) || (l.getTile(x+w*.99,y+h).type==TILE_SOLID && l.getTile(x+w,y+h/2).type!=TILE_SOLID))){
//println(""+(l.getTile(x+w/2,y+h-.0001).type==TILE_SOLID));
yspeed=.0001;
y=(double)((int)((double)(y+h)/(TILE_SIZE)+.001))*TILE_SIZE-h;
//println(""+(l.getTile(x+w/2,y+h-.0001).type==TILE_SOLID));
onGround=true;
}
if(yspeed < 0 && l.getTile(x+w/2,y).type==TILE_SOLID){
yspeed=0;
y+=((TILE_SIZE*height)-(y)*height%(TILE_SIZE*height)+.001)/height;
}
//Left&Right Collision
if(xspeed < 0 && l.getTile(x,y+h/2).type==TILE_SOLID){
xspeed=0;
x+=((TILE_SIZE*height)-(x-w*.01)*height%(TILE_SIZE*height)+.001)/height;
}
if(xspeed > 0 && l.getTile(x+w,y+h/2).type==TILE_SOLID){
xspeed=0;
x-=((x+w*1.01)*height%(TILE_SIZE*height)-.001)/height;
}
}
protected void collisionAction(MoverHandler m, IntVec movers){
//stuff
}
protected void checkMoverCollisions(Level l, MoverHandler m){
IntVec tiles = getContainingTiles(l);
IntVec foundMovers = new IntVec();
boolean foundM[1000] = {false};
for(int i=0; i<tiles.size(); i++){
IntVec moversOnTile = m.getOccupationTile(tiles.getVal(i));
for(int j=0; j<moversOnTile.size(); j++){
if(foundM[moversOnTile.getVal(j)] == false){
foundM[moversOnTile.getVal(j)] = true;
if(
(x<m.getMover(moversOnTile.getVal(j)).x || x<m.getMover(moversOnTile.getVal(j)).x+m.getMover(moversOnTile.getVal(j)).w) &&
(x+w>m.getMover(moversOnTile.getVal(j)).x || x+w>m.getMover(moversOnTile.getVal(j)).x+m.getMover(moversOnTile.getVal(j)).w) &&
(y<m.getMover(moversOnTile.getVal(j)).y || y<m.getMover(moversOnTile.getVal(j)).y+m.getMover(moversOnTile.getVal(j)).h) &&
(y+h>m.getMover(moversOnTile.getVal(j)).y || y+h>m.getMover(moversOnTile.getVal(j)).y+m.getMover(moversOnTile.getVal(j)).h)){
foundMovers.add(moversOnTile.getVal(j));
println(moversOnTile.getVal(j));
}
}
}
}
collisionAction(m, foundMovers);
}
protected void controller(Level l){
//for other objects
}
public void act(Level l, MoverHandler m){
//println(""+(y)+" "+((int)((double)(y+h)/(TILE_SIZE)+.001)*TILE_SIZE-h))
yspeed+=gravity;
xspeed*=friction;
numSteps=(int)(abs(max(xspeed,yspeed))/(TILE_SIZE/2)+1);
//numSteps=1;
int xorig=x;
int yorig=y;
for(int i=numSteps; i>0; i--){
x=xorig+(numSteps-i+1)*xspeed/numSteps;
y=yorig+(numSteps-i+1)*yspeed/numSteps;
if(levelCollisions) checkLevelCollisions(l);
if(moverCollisions) checkMoverCollisions(l, m);
}
controller(l, m);
}
public IntVec getContainingTiles(Level l){
IntVec tiles = new IntVec();
for(int i=(int)(x/TILE_SIZE); i<(int)((x+w)/TILE_SIZE+1); i++){
for(int j=(int)(y/TILE_SIZE); j<(int)((y+h)/TILE_SIZE+1); j++){
if(i>0 && i<l.getWidth() && j>0 && j<l.getHeight())
tiles.add(i+j*l.getWidth());
}
}
return tiles;
}
public void draw(Level l){
if(l.isOnScreen(x,y,width,height)){
stroke(255, 255, 255, 100);
fill(255, 255, 255, 255);
strokeWeight(12);
rect((x-l.getOffsetX())*height, (y-l.getOffsetY())*height, w*height, h*height);
}
}
}
public class Bullet extends Mover{
public Bullet(){
super();
w=.01;
h=.01;
moverCollisions=true;
levelCollisions=false;
}
protected void collisionAction(MoverHandler m, IntVec movers){
for(int i=0; i<movers.size(); i++){
m.removeMover(movers.getVal(i));
}
}
}
public class PhysicsMover extends Mover{
public PhysicsMover(){
super();
friction = .8;
gravity = .0025;
}
}
public class Player extends PhysicsMover{
public Player(){
super();
levelCollisions=true;
}
protected void controller(Level l, MoverHandler m){
if(onGround){
if(Keys[UP]){
yspeed=-.03;
}
}
//if(Keys[DOWN]) yspeed=.03;
//Left&Right Acceleration
if(Keys[RIGHT] && xspeed < .02){
xspeed+=.005;
if(xspeed > .02) xspeed = .02
}
if(Keys[LEFT] && xspeed > -.02){
xspeed-=.005;
if(xspeed < -.02) xspeed = -.02
}
//Left&Right Stage Scrolling
if(x-l.getOffsetX() > width/height*.6)
l.setOffsetX(l.getOffsetX()-.5*(l.getOffsetX()-(x-width/height*.6)));
if(x-l.getOffsetX() < width/height*.4){
l.setOffsetX(l.getOffsetX()-.5*(l.getOffsetX()-(x-width/height*.4)));
if(l.getOffsetX() < 0) l.setOffsetX(0);
}
//Up&Down Stage Scrolling
if(y-l.getOffsetY() > .6)
l.setOffsetY(l.getOffsetY()-.5*(l.getOffsetY()-(y-.6)));
if(y-l.getOffsetY() < .6){
l.setOffsetY(l.getOffsetY()-.5*(l.getOffsetY()-(y-.6)));
if(l.getOffsetY() < 0) l.setOffsetY(0);
}
if(Keys[DOWN]){
Bullet b = new Bullet();
b.x = x+w*2;
b.y = y+h/2;
//b.xspeed = .05;
m.addMover(b);
}
if(Keys[CONTROL]){
Box b = new Box();
b.x = x;
b.y = y;
m.addMover(b);
}
}
}
public class Box extends PhysicsMover{
public Box(){
super();
levelCollisions=true;
}
protected void controller(Level l){
/*if(Keys[UP] && xspeed > -.02){
xspeed-=.005;
if(xspeed < -.02) xspeed = -.02
}*/
}
}
public class MoverHandler{
private Mover[] movers;
private IntVec[] occupied;
private int numMovers;
public MoverHandler(){
movers = new Mover[1000];
numMovers = 0;
}
public void updateOccupationMap(Level l){
occupied = new IntVec[l.getWidth()*l.getHeight()];
for(int i=0; i<l.getWidth()*l.getHeight(); i++){
occupied[i] = new IntVec();
}
for(int i=0; i<numMovers; i++){
IntVec tempvec = movers[i].getContainingTiles(l);
for(int j=0; j<tempvec.size(); j++){
occupied[tempvec.getVal(j)].add(i);
}
}
}
public IntVec getOccupationTile(int index){
return occupied[index];
}
public void addMover(Mover m){
movers[numMovers++] = m;
}
public void removeMover(int index){
movers[index] = movers[--numMovers];
}
public int getNumMovers(){
return numMovers;
}
public Mover getMover(int index){
return movers[index];
}
public void actMovers(Level l){
updateOccupationMap(l);
for(int i=0; i<numMovers; i++){
movers[i].act(l,this);
}
}
public void drawMovers(Level l){
for(int i=0; i<numMovers; i++){
movers[i].draw(l);
}
}
}
Level l;
boolean Keys[256] = {0};
MoverHandler m;
void setup(){
size(600, 400);
m = new MoverHandler();
m.addMover(new Player());
PImage img = loadImage(MAP1);
img.loadPixels();
l = new Level(img.width, img.height);
color cblack = color(0, 0, 0);
for(int j=0; j<img.height; j++){
for(int i=0; i<img.width; i++){
l.getTile(i*TILE_SIZE,j*TILE_SIZE).type=(img.get(i,j) == cblack);
}
}
background(0,70,70);
smooth();
frameRate(30);
}
void draw() {
background(0,70,70);
m.actMovers(l);
l.Draw();
m.drawMovers(l);
}
void keyPressed() {
Keys[keyCode] = true;
}
void keyReleased() {
Keys[keyCode] = false;
}
void mouseDragged() {
l.getTile((double)mouseX/(double)height+l.getOffsetX(),(double)mouseY/(double)height+l.getOffsetY()).type=TILE_SOLID;
if(mouseButton == RIGHT){
l.getTile((double)mouseX/(double)height+l.getOffsetX(),(double)mouseY/(double)height+l.getOffsetY()).type=TILE_NONE;
}
}