Code is in Java. Screen0 class updates and renders a quest giver npc. Screen1 class updates and renders 9 pigs. Only one instance of each class is created when the user enters the main menu state of the game. <-Let me know if this is actually allowed or if I need to change it somehow. Only one map is update and drawn on screen therefore only things on that one map also gets update and render which is performed in the Game class. The logic of update and render itself are in written in each map since each map is derived as a Sprite class, a class that can update and render.
The game is 2D top-down RPG. The wall collision code is in each map class (the code that needs to set the camera coordinates).
It seems I have more control over the maps doing it this way, but it might just be me.
Camera speed controls how fast everything around the main character moves since everything around the main character is drawn relative to the camera. The main character is locked at the centered of the screen even if its action state is running. The set on the camera coordinate in the wall collision code is to make the camera not move on the character collides with the wall so it would make "appear" that link is "actually" colliding with the wall.
Screen1 class handles drawing the loot dropped by the pigs and erases all the loot when the pigs are all killed. When pigs all get killed and when the main character goes to a different screen, the pigs are back to full health.
The two maps uses the same map texture so they share the same directory for that texture.
package com.nicholaskong.Game.MapScreen;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import com.nicholaskong.Game.Animation;
import com.nicholaskong.Game.Camera;
import com.nicholaskong.Game.MapTracker;
import com.nicholaskong.Game.Sprite;
import com.nicholaskong.Game.Dialogue.Dialogue;
import com.nicholaskong.Game.DialogueSystem.NPC;
import com.nicholaskong.Game.GameCharacters.Soldier;
import com.nicholaskong.Game.GameCharacters.Link;
public class Screen0 extends Sprite
{
private Animation anim;
private NPC soldier;
private static String[] animations = {"src/screen/screen0.png"};
private Rectangle leftRectangle;
private ArrayList<NPC> npcList;
private Rectangle rightRectangle;
private Rectangle topRectangle;
private Rectangle downRectangle;
private static final int frameInterval = 0;
public Screen0(double x, double y) {
super(x, y);
anim = new Animation(animations,frameInterval);
Dialogue dialogue = new Dialogue();
soldier = new NPC(new Soldier(getWidth() - (getWidth() * .66) , (getHeight() - (getHeight() * 1.2)) ),dialogue);
npcList = new ArrayList<>();
MapTracker.SCREEN = 0;
npcList.add(soldier);
}
public int getX()
{
return super.getX();
}
public int getY()
{
return super.getY();
}
public int getWidth()
{
return anim.getWidth();
}
public int getHeight()
{
return anim.getHeight();
}
public Rectangle getLeftRectangle()
{
return leftRectangle;
}
public Rectangle getRightRectangle()
{
return rightRectangle;
}
public Rectangle getTopRectangle()
{
return topRectangle;
}
public Rectangle getDownRectangle()
{
return downRectangle;
}
public void update(Camera camera, Link link) {
int rectWidth = 50;
int rectHeight = 50;
// left
leftRectangle = new Rectangle(((int)(getWidth() * -.04)) - camera.getX(),getY() - camera.getY(),rectWidth,getHeight());
// right
rightRectangle = new Rectangle(((int)(getWidth())) - camera.getX(),getY() - camera.getY(),rectWidth,getHeight());
// top
topRectangle = new Rectangle((int)(getWidth() * 0)- camera.getX(),(int) ((getHeight() * -0.06) - camera.getY()) ,getWidth(),rectHeight);
// down
downRectangle = new Rectangle((int)(getWidth() * 0)- camera.getX(),getHeight() - camera.getY() ,getWidth(),rectHeight);
if(link.getRectangle().intersects(leftRectangle))
{
MapTracker.SCREEN = 1;
}
// right wall collision
else if(link.getX() + link.getIdleRightWidth() > ((int)(getWidth())) - camera.getX())
{
camera.setX(camera.getX() - camera.getSpeed());
}
// top wall collision
else if(link.getY() < (int) ((getHeight() * -0.06) - camera.getY()) + topRectangle.getHeight() - 10 )
{
camera.setY(camera.getY() + camera.getSpeed());
}
// down wall collision
else if( (link.getY() + link.getIdleDownHeight() > downRectangle.getY()))
{
camera.setY(camera.getY() - camera.getSpeed());
}
}
public ArrayList<NPC> getNPCsInMap()
{
return npcList;
}
public void draw(Graphics2D g2D, Camera camera)
{
int rectWidth = 50;
g2D.setColor(Color.BLUE);
g2D.drawImage(anim.getImage(),super.getX() - camera.getX(),super.getY()- camera.getY(),null);
//left
g2D.fillRect(((int)(getWidth() * -.04))- camera.getX(),getY() - camera.getY(),rectWidth , getHeight());
// draw all npcs on the map
for(int i = 0; i < npcList.size();i++)
{
npcList.get(i).draw(g2D, camera);
}
}
@Override
public void update(Camera camera) {
// TODO Auto-generated method stub
}
}
package com.nicholaskong.Game.MapScreen;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import com.nicholaskong.Game.ActionState;
import com.nicholaskong.Game.Animation;
import com.nicholaskong.Game.Camera;
import com.nicholaskong.Game.Collidable;
import com.nicholaskong.Game.MapTracker;
import com.nicholaskong.Game.Sprite;
import com.nicholaskong.Game.DialogueSystem.NPC;
import com.nicholaskong.Game.GameCharacters.Link;
import com.nicholaskong.Game.Monsters.Pig;
public class Screen1 extends Sprite
{
private Animation anim;
private static String[] animations = {"src/screen/screen0.png"};
private Rectangle rightRectangle;
private ArrayList<Collidable> monsterList;
private ArrayList<Collidable> projectileList;
private static final int frameInterval = 0;
private int numOfMonsters = 9;
private double[] widthData = {1.3,1.31,1.32,1.33,1.34,1.35,1.36,1.37,1.38 };
private double[] heightData = {0.90,0.83,0.76,0.69,0.62,0.55,0.48,0.41,0.34 };
private int[] behaviorData = {10,280,190,370,100,460,90,210,137 };
private ArrayList<Collidable> lootList;
private Rectangle leftRectangle;
private Rectangle topRectangle;
private Rectangle bottomRectangle;
public Screen1(double x, double y) {
super(x, y);
anim = new Animation(animations,frameInterval);
monsterList = new ArrayList<>();
lootList = new ArrayList<>();
for(int i = 0; i < numOfMonsters;i++)
{
Pig pig = new Pig(getWidth() - (getWidth() * widthData[i]),getHeight() - (getHeight() * heightData[i]));
pig.setBehaviorCounter(behaviorData[i]);
monsterList.add(pig);
}
projectileList = new ArrayList<>();
rightRectangle = new Rectangle(0,0,(int)( .50 * getWidth()),getHeight());
}
public int getX()
{
return super.getX();
}
public int getY()
{
return super.getY();
}
public int getWidth()
{
return anim.getWidth();
}
public int getHeight()
{
return anim.getHeight();
}
public Rectangle getRightRectangle()
{
return rightRectangle;
}
public Rectangle getTopRectangle()
{
return topRectangle;
}
public ArrayList<NPC> getNPCsInMap()
{
return npcList;
}
public void update(Camera camera, Link link) {
int rectWidth = 50;
int rectHeight = 50;
rightRectangle = new Rectangle((int)(getWidth() * .16 ) - camera.getX(),getY() - camera.getY(),50,getHeight());
leftRectangle = new Rectangle((int)((getX())- camera.getX() - rectWidth),getY() - camera.getY(),rectWidth , getHeight());
topRectangle = new Rectangle((int)((getX())- camera.getX()),getY() - camera.getY() - rectHeight,getWidth() , rectHeight);
bottomRectangle = new Rectangle((int)((getX())- camera.getX()),getY() - camera.getY() + getHeight(),getWidth() , rectHeight);
if(link.getRectangle().intersects(rightRectangle))
{
MapTracker.SCREEN = 0;
}
else if(link.getX() <= leftRectangle.getX() + leftRectangle.getWidth())
{
camera.setX(camera.getX() + camera.getSpeed());
}
else if(link.getY() <= topRectangle.getY() + topRectangle.getHeight() - 5)
{
camera.setY(camera.getY() + camera.getSpeed());
}
else if(link.getY() + link.getIdleDownHeight() > bottomRectangle.getY())
{
camera.setY(camera.getY() - camera.getSpeed());
}
if(numOfMonsters == 0 && MapTracker.SCREEN == 0)
{
lootList.removeAll(lootList);
numOfMonsters = 9;
for(int i = 0; i < numOfMonsters;i++)
{
Collidable mob = monsterList.get(i);
mob.setLife(mob.getMaxLife());
mob.setState(ActionState.RUNNING);
}
}
for(int i = 0; i < monsterList.size();i++)
{
Collidable mob = monsterList.get(i);
if(mob.getLife() == 0)
{
lootList.add(mob.getGold());
link.addExp(link.getExp() + mob.getExp());
numOfMonsters--;
}
if(mob.getLife() >= 0)
{
mob.update(camera);
}
}
}
public ArrayList<Collidable> getMonstersOnMap()
{
return monsterList;
}
public void draw(Graphics2D g2D, Camera camera)
{
int rectWidth = 50;
g2D.setColor(Color.BLUE);
g2D.drawImage(anim.getImage(),getX() - camera.getX(),getY()- camera.getY(),null);
// right
g2D.fillRect((int)((getWidth() * .16 )- camera.getX()),getY() - camera.getY(),rectWidth , getHeight());
// draw and update all monsters on the map
for(int i = 0; i < monsterList.size();i++)
{
Collidable mob = monsterList.get(i);
mob.draw(g2D, camera);
}
// draw all the loots
for(int i = 0; i < lootList.size();i++)
{
Collidable loot = lootList.get(i);
loot.update(camera);
loot.draw(g2D, camera);
}
}
public void update(Camera camera) {
// TODO Auto-generated method stub
}
public ArrayList<Collidable> getLootsOnMap()
{
return lootList;
}
public ArrayList<Collidable> getProjectilesInMap()
{
return projectileList;
}
}