I am making an RPG game, however, I have an error at the moment. The player's character can move in all four cardinal directions, but the player becomes stuck if you move right, up or down.
Also, the error seems to have some logic to it:
if moving down, the character is stuck in a loop moving down
unless the up arrow is pressed, then the player will begin a new infinite loop for up
unless the right arrow is pressed, then the player will begin a new infinite loop for right
So right seems to take precedence over up which takes precedence over down.
Strangely, the leftward movement works perfectly. Even when the character is stuck in an infinite loop, the left arrow key will always cause the player to move left in the correct way.
I don't understand where the error is in my code. I don't know why the leftward movement works while the other three directions do not. I don't understand why there seems to be some sort of priority ordering between the other three directions as well.
I have looked through the program and I don't think I treat leftward movement differently to any other direction. However, I might be wrong, considering this error.
Due to the 30k word limit, I do not have enough space to include all the code here. Therefore, I have included a link to my github, so you can see the code there instead.
https://github.com/davey67/bludbourne
I think these classes are probably the most important classes though:
package com.bludbourne.game.desktop;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.bludbourne.game.BludBourne;
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.title="BludBourne";
config.useGL30=false;
config.width =480;
config.height=480;
Application app = new LwjglApplication(new BludBourne(),config);
Gdx.app=app;
Gdx.app.setLogLevel(Application.LOG_DEBUG);
}
}
/
package com.bludbourne.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.bludbourne.game.screens.MainGameScreen;
import com.badlogic.gdx.Game;
public class BludBourne extends Game {
public static final MainGameScreen _mainGameScreen = new MainGameScreen();
#Override
public void create () {
setScreen(_mainGameScreen);
}
#Override
public void dispose () {
_mainGameScreen.dispose();
}
}
/
package com.bludbourne.game;
import java.util.HashMap;
import java.util.Map;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.math.Vector3;
public class PlayerController implements InputProcessor
{
private final static String TAG = PlayerController.class.getSimpleName();
enum Keys{
LEFT,RIGHT,UP,DOWN,QUIT
}
enum Mouse{
SELECT,DOACTION
}
private static Map<Keys,Boolean> keys=new HashMap<PlayerController.Keys,Boolean>();
private static Map<Mouse,Boolean> mouseButtons = new HashMap<PlayerController.Mouse,Boolean>();
private Vector3 lastMouseCoordinates;
static {
keys.put(Keys.LEFT,false);
keys.put(Keys.RIGHT,false);
keys.put(Keys.UP,false);
keys.put(Keys.DOWN, false);
keys.put(Keys.QUIT, false);
}
static {
mouseButtons.put(Mouse.SELECT, false);
mouseButtons.put(Mouse.DOACTION, false);
}
private Entity _player;
public PlayerController(Entity player) {
this.lastMouseCoordinates=new Vector3();
this._player=player;
}
#Override
public boolean keyDown(int keycode)
{
if(keycode ==Input.Keys.LEFT||keycode==Input.Keys.A) {
this.leftPressed();
}
if(keycode ==Input.Keys.RIGHT||keycode==Input.Keys.D) {
this.rightPressed();
}
if(keycode ==Input.Keys.UP||keycode==Input.Keys.W) {
this.upPressed();
}
if(keycode ==Input.Keys.DOWN||keycode==Input.Keys.S) {
this.downPressed();
}
if(keycode==Input.Keys.Q) {
this.quitPressed();
}
return true;
}
#Override
public boolean keyUp(int keycode)
{
if(keycode ==Input.Keys.LEFT||keycode==Input.Keys.A) {
this.leftReleased();
}
if(keycode ==Input.Keys.RIGHT||keycode==Input.Keys.D) {
this.rightReleased();
}
if(keycode ==Input.Keys.UP||keycode==Input.Keys.W) {
this.upReleased();
}
if(keycode ==Input.Keys.DOWN||keycode==Input.Keys.S) {
this.downReleased();
}
if(keycode==Input.Keys.Q) {
this.quitReleased();
}
return true;
}
#Override
public boolean keyTyped(char character)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button)
{
if(button==Input.Buttons.LEFT||button==Input.Buttons.RIGHT) {
this.setClickedMouseCoordinates(screenX,screenY);
}
if(button==Input.Buttons.LEFT) {
this.selectMouseButtonPressed(screenX,screenY);
}
if(button==Input.Buttons.RIGHT) {
this.doActionMouseButtonPressed(screenX,screenY);
}
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button)
{
if(button==Input.Buttons.LEFT) {
this.selectMouseButtonReleased(screenX,screenY);
}
if(button==Input.Buttons.RIGHT) {
this.doActionMouseButtonReleased(screenX,screenY);
}
return true;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean scrolled(int amount)
{
// TODO Auto-generated method stub
return false;
}
public void dispose() {
}
public void leftPressed() {
keys.put(Keys.LEFT,true);
}
public void rightPressed() {
keys.put(Keys.RIGHT,true);
}
public void upPressed() {
keys.put(Keys.UP,true);
}
public void downPressed() {
keys.put(Keys.DOWN,true);
}
public void quitPressed() {
keys.put(Keys.QUIT, true);
}
public void setClickedMouseCoordinates(int x,int y) {
lastMouseCoordinates.set(x,y,0);
}
public void selectMouseButtonPressed(int x,int y) {
mouseButtons.put(Mouse.SELECT,true);
}
public void doActionMouseButtonPressed(int x,int y) {
mouseButtons.put(Mouse.DOACTION, true);
}
public void leftReleased() {
keys.put(Keys.LEFT,false);
}
public void rightReleased() {
keys.put(Keys.RIGHT,true);
}
public void upReleased() {
keys.put(Keys.UP,true);
}
public void downReleased() {
keys.put(Keys.DOWN,true);
}
public void quitReleased() {
keys.put(Keys.QUIT, true);
}
public void selectMouseButtonReleased(int x,int y) {
mouseButtons.put(Mouse.SELECT, false);
}
public void doActionMouseButtonReleased(int x ,int y) {
mouseButtons.put(Mouse.DOACTION, false);
}
public void update(float delta) {
processInput(delta);
}
public static void hide() {
keys.put(Keys.LEFT, false);
keys.put(Keys.RIGHT, false);
keys.put(Keys.UP, false);
keys.put(Keys.DOWN, false);
keys.put(Keys.QUIT, false);
}
private void processInput(float delta) {
if(keys.get(Keys.LEFT)) {
_player.calculateNextPosition(Entity.Direction.LEFT,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.LEFT,delta);
}
else if(keys.get(Keys.RIGHT)) {
_player.calculateNextPosition(Entity.Direction.RIGHT,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.RIGHT,delta);
}
else if(keys.get(Keys.UP)) {
_player.calculateNextPosition(Entity.Direction.UP,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.UP,delta);
}
else if(keys.get(Keys.DOWN)) {
_player.calculateNextPosition(Entity.Direction.DOWN,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.DOWN,delta);
}
else if(keys.get(Keys.QUIT)) {
Gdx.app.exit();
}
else {
_player.setState(Entity.State.IDLE);
}
if(mouseButtons.get(Mouse.SELECT)) {
mouseButtons.put(Mouse.SELECT, false);
}
}
}
/
package com.bludbourne.game;
import java.util.UUID;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
public class Entity
{
private static final String TAG = Entity.class.getSimpleName();
private static final String _defaultSpritePath = "sprites/characters/Warrior.png";
private Vector2 _velocity;
private String _entityID;
private Direction _currentDirection = Direction.LEFT;
private Direction _previousDirection = Direction.UP;
private Animation _walkLeftAnimation;
private Animation _walkRightAnimation;
private Animation _walkUpAnimation;
private Animation _walkDownAnimation;
private Array<TextureRegion> _walkLeftFrames;
private Array<TextureRegion> _walkRightFrames;
private Array<TextureRegion> _walkUpFrames;
private Array<TextureRegion> _walkDownFrames;
protected Vector2 _nextPlayerPosition;
protected Vector2 _currentPlayerPosition;
protected State _state = State.IDLE;
protected float _frameTime = 0f;
protected Sprite _frameSprite = null;
protected TextureRegion _currentFrame = null;
public final int FRAME_WIDTH = 16;
public final int FRAME_HEIGHT = 16;
public static Rectangle boundingBox;
public enum State
{
IDLE, WALKING
}
public enum Direction
{
UP, RIGHT, DOWN, LEFT
}
public Entity() {
initEntity();
}
public void initEntity()
{
this._entityID = UUID.randomUUID().toString();
this._nextPlayerPosition = new Vector2();
this._currentPlayerPosition = new Vector2();
this.boundingBox = new Rectangle();
this._velocity = new Vector2(2f, 2f);
Utility.loadTextureAsset(_defaultSpritePath);
loadDefaultSprite();
loadAllAnimations();
}
public void update(float delta)
{
_frameTime = (_frameTime + delta) % 5;
setBoundingBoxSize(0f, 0.5f);
}
public void init(float startX, float startY)
{
this._currentPlayerPosition.x = startX;
this._currentPlayerPosition.y = startY;
this._nextPlayerPosition.x = startX;
this._nextPlayerPosition.y = startY;
}
public void setBoundingBoxSize(float percentageWidthReduced, float percentageHeightReduced)
{
float width;
float height;
float widthReductionAmount = 1.0f - percentageWidthReduced;
float heightReductionAmount = 1.0f - percentageHeightReduced;
if (widthReductionAmount > 0 && widthReductionAmount < 1)
{
width = FRAME_WIDTH * widthReductionAmount;
}
else
{
width = FRAME_WIDTH;
}
if (heightReductionAmount > 0 && heightReductionAmount < 1)
{
height = FRAME_HEIGHT * heightReductionAmount;
}
else
{
height = FRAME_HEIGHT;
}
if (width == 0 || height == 0)
{
Gdx.app.debug(TAG, "Width and Height are 0!! " + width + ":" + height);
}
float minX;
float minY;
if (MapManager.UNIT_SCALE > 0)
{
minX = _nextPlayerPosition.x / MapManager.UNIT_SCALE;
minY = _nextPlayerPosition.y / MapManager.UNIT_SCALE;
}
else
{
minX = _nextPlayerPosition.x;
minY = _nextPlayerPosition.y;
}
boundingBox.set(minX, minY, width, height);
}
private void loadDefaultSprite()
{
Texture texture = Utility.getTextureAsset(_defaultSpritePath);
TextureRegion[][] textureFrames = TextureRegion.split(texture, FRAME_WIDTH, FRAME_HEIGHT);
_frameSprite = new Sprite(textureFrames[0][0].getTexture(), 0, 0, FRAME_WIDTH, FRAME_HEIGHT);
_currentFrame = textureFrames[0][0];
}
public void loadAllAnimations()
{
Texture texture = Utility.getTextureAsset(_defaultSpritePath);
TextureRegion[][] textureFrames = TextureRegion.split(texture, FRAME_WIDTH, FRAME_HEIGHT);
_walkDownFrames = new Array<TextureRegion>(4);
_walkLeftFrames = new Array<TextureRegion>(4);
_walkRightFrames = new Array<TextureRegion>(4);
_walkUpFrames = new Array<TextureRegion>(4);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
TextureRegion region=textureFrames[i][j];
if(region==null) {
Gdx.app.debug(TAG, "Got null animation frame "+i+","+j);
}
switch(i) {
case 0:
_walkDownFrames.insert(j,region);
break;
case 1:
_walkLeftFrames.insert(j,region);
break;
case 2:
_walkRightFrames.insert(j,region);
break;
case 3:
_walkUpFrames.insert(j,region);
break;
}
}
}
_walkDownAnimation = new Animation(0.25f,_walkDownFrames,Animation.PlayMode.LOOP);
_walkLeftAnimation = new Animation(0.25f,_walkLeftFrames,Animation.PlayMode.LOOP);
_walkRightAnimation = new Animation(0.25f,_walkRightFrames,Animation.PlayMode.LOOP);
_walkUpAnimation = new Animation(0.25f,_walkUpFrames,Animation.PlayMode.LOOP);
}
public void dispose() {
Utility.unloadAsset(_defaultSpritePath);
}
public void setState(State state) {
this._state = state;
}
public Sprite getFrameSprite() {
return _frameSprite;
}
public TextureRegion getFrame() {
return _currentFrame;
}
public Vector2 getCurrentPosition() {
return _currentPlayerPosition;
}
public void setCurrentPosition(float currentPositionX,float currentPositionY) {
_frameSprite.setX(currentPositionX);
_frameSprite.setY(currentPositionY);
this._currentPlayerPosition.x=currentPositionX;
this._currentPlayerPosition.y=currentPositionY;
}
public void setDirection(Direction direction,float deltaTime) {
this._previousDirection=this._currentDirection;
this._currentDirection=direction;
switch(_currentDirection) {
//not sure about this
case DOWN:
_currentFrame=(TextureRegion) _walkDownAnimation.getKeyFrame(_frameTime);
break;
case LEFT:
_currentFrame=(TextureRegion) _walkLeftAnimation.getKeyFrame(_frameTime);
break;
case RIGHT:
_currentFrame=(TextureRegion) _walkRightAnimation.getKeyFrame(_frameTime);
break;
case UP:
_currentFrame=(TextureRegion) _walkUpAnimation.getKeyFrame(_frameTime);
break;
default:
break;
}
}
public void setNextPositionToCurrent() {
setCurrentPosition(_nextPlayerPosition.x,_nextPlayerPosition.y);
}
public void calculateNextPosition(Direction currentDirection,float deltaTime) {
float testX=_currentPlayerPosition.x;
float testY=_currentPlayerPosition.y;
_velocity.scl(deltaTime);
switch(currentDirection) {
case LEFT:
testX-=_velocity.x;
break;
case RIGHT:
testX+=_velocity.x;
break;
case UP:
testY+=_velocity.y;
break;
case DOWN:
testY-=_velocity.y;
break;
default:
break;
}
_nextPlayerPosition.x=testX;
_nextPlayerPosition.y=testY;
_velocity.scl(1/deltaTime);
}
}
I feel that I am probably missing something obvious, however, I still cannot see the error. Help is much appreciated. Thank you.
My github also contains the sprite sheet and the three maps, all of which would be stored in the asset folder of my project.
May I draw your attention to these four methods in PlayerInput
public void leftReleased() {
keys.put(Keys.LEFT,false);
}
public void rightReleased() {
keys.put(Keys.RIGHT,true);
}
public void upReleased() {
keys.put(Keys.UP,true);
}
public void downReleased() {
keys.put(Keys.DOWN,true);
}
I believe it should be false, not true when the key is released. I've verified that this prevents the infinite loop.
The priority order of right, up, then down is due to the order in which the keys are checked in processInput.
Related
When I drag the shapes that I drew, I want to move.
but I do not know how to do it.
I have tried the make move method in GPanel but could not make it.
knowledge.
I have been working on this for almost 1 week and tried all the solutions that I could think of.
This is my first time posting a code question on stack overflow.
I do really want to learn.
. And love you all.
I hope one day I could be a savior for code newbies
Have to use affine transform
this is drawing page
package frame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.Vector;
import javax.swing.JPanel;
import main.GConstants.EAnchorLocation;
import main.GConstants.EDrawingStyle;
import shapeTool.GShapeTool;
public class GPanel extends JPanel {
private static final long serialVersionUID = 1L;
private GShapeTool shapeTool;
private GShapeTool selectedShape;
private Vector<GShapeTool> shapes;
public GPanel() {
this.setBackground(Color.WHITE);
this.shapes = new Vector<GShapeTool>();
MouseHandler mouseHandler = new MouseHandler();
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
this.addMouseWheelListener(mouseHandler);
}
public void initialize() {}
public Vector<GShapeTool> getShapes() {
return this.shapes;
}
public void setShapes(Vector<GShapeTool> shapes){
this.shapes = shapes;
this.updateUI();
}
public void paint(Graphics graphics) {
super.paint(graphics);
for(GShapeTool shape: this.shapes) {
shape.draw((Graphics2D)graphics);
}
}
public void setShapeTool(GShapeTool shapeTool) {
this.shapeTool = shapeTool;
}
private boolean onShape(int x, int y) {
boolean shapeCheck = false;
for(GShapeTool shapeTool: this.shapes) {
if(shapeTool.contains(x, y)) {
this.selectedShape = shapeTool;
shapeCheck = true;
} else {
shapeTool.setSelected(false, (Graphics2D)getGraphics());
}
}
if(shapeCheck) {
this.selectedShape.setSelected(true, (Graphics2D)getGraphics());
}
return shapeCheck;
}
private void setInitialPoint(int x, int y) {
this.selectedShape = this.shapeTool.clone();
this.selectedShape.setInitialPoint(x, y);
}
private void setFinalPoint(int x, int y) {
for(GShapeTool shapeTool: this.shapes) {
shapeTool.setSelected(false, (Graphics2D)getGraphics());
}
// Graphics2D graphics2D = (Graphics2D) this.getGraphics();
//set xor mode;
// graphics2D.setXORMode(getBackground());
this.selectedShape.setFinalPoint(x, y);
this.selectedShape.setSelected(true, (Graphics2D)getGraphics());
this.shapes.add(this.selectedShape);
}
private void setIntermediatePoint(int x, int y) {
this.selectedShape.setIntermediatePoint(x, y);
}
private void animate(int x, int y) {
Graphics2D graphics2D = (Graphics2D) this.getGraphics();
//set xor mode;
graphics2D.setXORMode(getBackground());
this.selectedShape.animate(graphics2D, x, y);
}
private class MouseHandler
implements MouseListener, MouseMotionListener, MouseWheelListener {
private boolean isDrawing;
MouseHandler() {
this.isDrawing = false;
}
#Override
public void mouseClicked(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
if(e.getClickCount() == 1) {
this.mouseLButton1Clicked(e);
} else if(e.getClickCount() == 2) {
this.mouseLButton2Clicked(e);
}
} else if(e.getButton() == MouseEvent.BUTTON2) {
if(e.getClickCount() == 1) {
this.mouseRButton1Clicked(e);
}
}
}
#Override
public void mouseMoved(MouseEvent e) {
if(isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
animate(e.getX(), e.getY());
}
}
}
private void mouseLButton1Clicked(MouseEvent e) {
if(!this.isDrawing) {
if(!onShape(e.getX(), e.getY())) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
setInitialPoint(e.getX(), e.getY());
this.isDrawing = true;
}
}
else if(onShape(e.getX(), e.getY())) {
onShape(e.getX(), e.getY());
}
} else {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
setIntermediatePoint(e.getX(),e.getY());
}
}
}
private void mouseLButton2Clicked(MouseEvent e) {
if(this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
setFinalPoint(e.getX(), e.getY());
this.isDrawing = false;
}
}
}
private void mouseRButton1Clicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
if(!this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.e2PointDrawing) {
setInitialPoint(e.getX(), e.getY());
this.isDrawing = true;
}
}
}
}
#Override
public void mouseDragged(MouseEvent e) {
if(this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.e2PointDrawing) {
animate(e.getX(), e.getY());
}
}
}
#Override
public void mouseReleased(MouseEvent e) {
if(this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.e2PointDrawing) {
setFinalPoint(e.getX(), e.getY());
this.isDrawing = false;
}
}
}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseWheelMoved(MouseWheelEvent e) {}
}
}
this is abstract class for shapes
package shapeTool;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Double;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.Vector;
import main.GConstants.EAnchorLocation;
import main.GConstants.EDrawingStyle;
public abstract class GShapeTool implements Serializable {
private static final long serialVersionUID = 1L;
public enum EAnchors {
x0y0,
x0y1,
x0y2,
x1y0,
x1y2,
x2y0,
x2y1,
x2y2,
RR;
}
public final static int wAnchor = 10;
public final static int hAnchor = 10;
private EDrawingStyle eDrawingStyle;
protected boolean isSelected;
protected Shape shape;
private Ellipse2D[] anchors;
public GShapeTool(EDrawingStyle eDrawingStyle) {
this.eDrawingStyle = eDrawingStyle;
this.isSelected = false;
this.anchors = new Ellipse2D.Double[EAnchors.values().length];
for(EAnchors eAnchor: EAnchors.values()) {
this.anchors[eAnchor.ordinal()] = new Ellipse2D.Double();
}
}
public EDrawingStyle getDrawingStyle() {
return this.eDrawingStyle;
}
public boolean contains(int x, int y) {
return this.shape.contains(x , y);
}
private void drawAnchors(Graphics2D graphics2D) {
// draw bounding rectangle
Rectangle rectangle = this.shape.getBounds();
int x0 = rectangle.x-wAnchor;
int x1 = rectangle.x + rectangle.width/2;
int x2 = rectangle.x + rectangle.width;
int y0 = rectangle.y-hAnchor;
int y1 = rectangle.y + rectangle.height/2;
int y2 = rectangle.y + rectangle.height;
this.anchors[EAnchors.x0y0.ordinal()].setFrame(x0,y0,wAnchor,hAnchor);
this.anchors[EAnchors.x0y1.ordinal()].setFrame(x0,y1,wAnchor,hAnchor);
this.anchors[EAnchors.x0y2.ordinal()].setFrame(x0,y2,wAnchor,hAnchor);
this.anchors[EAnchors.x1y0.ordinal()].setFrame(x1,y0,wAnchor,hAnchor);
this.anchors[EAnchors.x1y2.ordinal()].setFrame(x1,y2,wAnchor,hAnchor);
this.anchors[EAnchors.x2y0.ordinal()].setFrame(x2,y0,wAnchor,hAnchor);
this.anchors[EAnchors.x2y1.ordinal()].setFrame(x2,y1,wAnchor,hAnchor);
this.anchors[EAnchors.x2y2.ordinal()].setFrame(x2,y2,wAnchor,hAnchor);
this.anchors[EAnchors.RR.ordinal()].setFrame(x1,y0-50,wAnchor,hAnchor);
//draw anchors
graphics2D.setColor(Color.BLACK);
for(EAnchors eAnchor: EAnchors.values()) {
graphics2D.draw(this.anchors[eAnchor.ordinal()]);
}
}
private void eraseAnchors(Graphics2D graphics2D) {
graphics2D.setColor(Color.WHITE);
for(EAnchors eAnchor: EAnchors.values()) {
graphics2D.draw(this.anchors[eAnchor.ordinal()]);
}
}
public void setSelected(boolean isSelected, Graphics2D graphics2D) {
if(this.isSelected) {
if(!isSelected) {
//erase
this.eraseAnchors(graphics2D);
}
} else {
if(isSelected) {
//draw
this.drawAnchors(graphics2D);
}
}
this.isSelected = isSelected;
}
public void draw(Graphics2D graphics) {
graphics.draw(this.shape);
}
public void animate(Graphics2D graphics2d, int x, int y) {
//erase;
this.draw(graphics2d);
// //move point
this.movePoint(x,y);
// //draw;
this.draw(graphics2d);
}
//interface
public abstract GShapeTool clone();
public abstract void setInitialPoint(int x, int y);
public abstract void setFinalPoint(int x, int y);
public abstract void setIntermediatePoint(int x, int y);
public abstract void movePoint(int x, int y);
}
and this is shape class that extends GShapeTool
package shapeTool;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import main.GConstants.EDrawingStyle;
public class GRectangle extends GShapeTool {
//attributes
private static final long serialVersionUID = 1L;
//components
//constructor
public GRectangle() {
super(EDrawingStyle.e2PointDrawing);
this.shape = new Rectangle();
}
#Override
public GShapeTool clone() {
GShapeTool cloned = new GRectangle();
return cloned;
}
// methods
#Override
public void setInitialPoint(int x, int y) {
Rectangle rectangle = (Rectangle) this.shape;
rectangle.setLocation(x, y);
rectangle.setSize(0, 0);
}
#Override
public void setIntermediatePoint(int x, int y) {
// TODO Auto-generated method stub
}
#Override
public void setFinalPoint(int x, int y) {
}
#Override
public void movePoint(int x, int y) {
Rectangle rectangle = (Rectangle) this.shape;
rectangle.setSize(x-rectangle.x, y-rectangle.y);
}
}
You should get a dragstart event. That is when you save the mouse position and the selected object(s).
When you get a dragfinished event, again note the mouse positon and move the objects accordingly. The move might just happen on the screen, but e.g. in case the drop occurred on the trashcan you want to delete them.
Now while the drag is active you might get a number of more dragging events, which you should use to update the screen and give feedback to the user. This would most of the time just be to look at the mouse positon and the selected objects and draw them accordingly.
We are making a six-player multiplayer game and I am responsible for a networking class. The game incorporates Slick 2D. In the game there are entities(code shown below)
package Game;
import org.newdawn.slick.*;
public abstract class Entity {
double maxHealth, health, speed, damage, width, height, locationX, locationY;
Animation standing, walkingLeft, walkingRight, attacking, jumping, current;
long pastTime = 0;
public boolean isReadyToAttack(long delta) {
if(pastTime < 2 * 500) { //multiply by 1000 to get milliseconds
pastTime += delta;
return false;
}else{
pastTime = 0;
return true;
}
}
public void setMaxHealth(double d){
maxHealth = d;
}
public void setHealth(double d){
health = d;
}
public void setSpeed(double x){
speed = x;
}
public void setDamage(double x){
damage = x;
}
public void setLocation(double x, double y){
locationX = x;
locationY = y;
}
public void setSprites(Animation s, Animation r){
standing = s;
walkingRight = r;
}
public void setCurrent(Animation a){
current = a;
}
public double getMaxHealth(){
return maxHealth;
}
public double getHealth(){
return health;
}
public double getSpeed(){
return speed;
}
public double getDamage(){
return damage;
}
public double getLocationX(){
return locationX;
}
public double getLocationY(){
return locationY;
}
public Animation getStanding(){
return standing;
}
public Animation getRight(){
return walkingRight;
}
public Animation getCurrent(){
return current;
}
public abstract double getAttackRange();
}
The entities class is also extended by the Heroes class which is further extended by the Ares class. Ares is one of the six characters in our game and when you start the game you can choose one of the six in the start menu.
Here is the Hero class:
package Game;
import org.newdawn.slick.Animation;
public abstract class Hero extends Entity{
static double gravity = 0.1;
double velocity;
int level;
boolean disabled, grounded = true;
public void setLevel(int i){
level = i;
}
public void setVelocity(double d){
velocity = d;
}
public void setDisabled(boolean b){
disabled = b;
}
public void setGrounded(boolean b){
grounded = b;
}
public int getLevel(){
return level;
}
public double getVelocity(){
return velocity;
}
public boolean getDisabled(){
return disabled;
}
public boolean getGrounded(){
return grounded;
}
public double getGravity(){
return gravity;
}
public boolean isAlive(){
if(getHealth() > 0)
return true;
return false;
}
public void attack(Entity gettingAttacked, Hero attacking) {
gettingAttacked.setHealth(gettingAttacked.getHealth() - attacking.getDamage());
}
public boolean isReadyToRegenerate(long delta) {
if(pastTime < 1 * 1000){
pastTime += delta;
return false;
}
else{
pastTime = 0;
return true;
}
}
public static void regenerate(Hero h, long delta){
if(h.getHealth() >= 0 && h.getHealth() < h.getMaxHealth())
if(h.isReadyToRegenerate(delta))
h.setHealth(h.getHealth() + (h.getMaxHealth()) * 0.01);
}
public abstract void levelUp();
}
Here is the Ares class:
package Game;
import org.newdawn.slick.Animation;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
public class Ares extends Hero {
public Ares() throws SlickException {
setHealth(500);
setSpeed(0.4);
setDamage(70);
setLocation(850,625);
setSprites(new Animation(new SpriteSheet("res/Ares.png", 191, 275), 200), new Animation(new SpriteSheet("res/AresWalk.png", 191, 275), 200));
}
public void levelUp() {
level += 1;
health *= 1.1;
damage *= 1.1;
}
public double getAttackRange() {
return 250;
}
public double maxHealth() {
return 500;
}
}
Here is the Battle code, which contains the main gameplay code, the code is currently uncompleted and only has movement:
package Game;
import java.util.ArrayList;
import org.lwjgl.input.*;
import org.newdawn.slick.*;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.state.*;
public class Battle extends BasicGameState {
private ArrayList<Entity> entities = new ArrayList<Entity>();
private Hero player;
private Image background;
private int midScreen, ground;
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
gc.setVSync(true);
player = new Ares();
player.setCurrent(player.getStanding());
entities.add(player);
background = new Image("res/Background.png");
midScreen = 800;
ground = 625;
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
g.translate((float)-player.getLocationX() + midScreen, (float)-player.getLocationY() + ground);
background.draw(0, -920);
for(int i = 0; i < entities.size(); i++)
entities.get(i).getCurrent().draw((float)entities.get(i).getLocationX(), (float)entities.get(i).getLocationY());
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
player.getCurrent().update(delta); // ensures
Input kb = gc.getInput();
if (kb.isKeyDown(Input.KEY_SPACE) && player.getGrounded()) {
player.setGrounded(false);
player.setVelocity(7);
player.setLocation(player.getLocationX(), player.getLocationY() - player.getVelocity());
player.setCurrent(player.getStanding());
}
else if (kb.isKeyDown(Input.KEY_A) && player.getLocationX() > 800) {
player.setLocation(player.getLocationX() - player.getSpeed() * delta, player.getLocationY());
if(player.grounded)
player.setCurrent(player.getRight());
}
else if (kb.isKeyDown(Input.KEY_D) && player.getLocationX() < 8580) {
player.setLocation(player.getLocationX() + player.getSpeed() * delta, player.getLocationY());
if(player.grounded)
player.setCurrent(player.getRight());
}
else
player.setCurrent(player.getStanding());
if (Math.abs(player.getLocationY() - ground) < .01)
player.setGrounded(true);
if (player.getGrounded() == false) {
player.setVelocity(player.getVelocity() - player.getGravity());
player.setLocation(player.getLocationX(), player.getLocationY() - player.getVelocity());
}
}
public int getID(){
return 1;
}
}
What I am having difficulty with is creating a server and client that gets the input from the players, such as location, who chose which player, etc. I'm wondering that if in Battle, when Player objects are made, how would I be able to get location and other specific attributes of the objects and give them to the other computers.
Note: I am coding in Java, and trying to use a TCP connection to code this. I am open to UDP if you think it may be easier. Just give a basic overview of what needs to be done and perhaps a little code, do not simply give me the answer please.
I'm very new to game design (this is my first attempt) and this project will be used to create an android game.
I'm trying to make a simple game (as simple as possible).
What I need:
A background
a ship (that can move left an right at the bottom of the screen)
Enemies (Bombs dropping down from the sky)
projectiles (to shoot bombs with, shoot straight up)
Score (in the upper corner)
I have studied this tutorial:
http://www.kilobolt.com/game-development-tutorial.html
and changed code to get this:
http://i297.photobucket.com/albums/mm231/mabee84/Battleship.png
the black rectangles are projectiles.
Now I need to create the bombs but I can't figure out how to implement them.
they need to spawn at fixed y-value and a random x-value (within the screen)
Upon shooting on the bombs they should die but if bombs hit the ship game is over.
Please help i'm a bit stuck.
package kiloboltgame;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import java.util.ArrayList;
public class StartingClass extends Applet implements Runnable, KeyListener {
private Ship ship;
public static Bomb b1, b2;
public static int score = 0;
private Font font = new Font(null, Font.BOLD, 30);
private Image image, Battleship, Background, Bomb;
private static Background bg1, bg2;
private URL base;
private Graphics second;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("BattleShip");
try{
base = getDocumentBase();
}catch (Exception e){
//TODO: handle exception
}
//Image Setups
Battleship = getImage(base, "data/Battleship.png");
Background = getImage(base, "data/Background.png");
Bomb = getImage(base, "data/Bomb1.png");
}
#Override
public void start() {
bg1 = new Background(0, 0);
bg2 = new Background(800, 0);
ship = new Ship();
b1 = new Bomb(340, 100);
b2 = new Bomb(700, 100);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
ship.update();
ArrayList projectiles = ship.getProjectiles();
for(int i = 0; i < projectiles.size(); i++){
Projectile p = (Projectile) projectiles.get(i);
if(p.isVisible() == true){
p.update();
}else{
projectiles.remove(i);
}
}
b1.update();
b2.update();
bg1.update();
bg2.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if(image == null){
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(Background, bg1.getBgX(), bg1.getBgY(), this);
ArrayList projectiles = ship.getProjectiles();
for(int i = 0; i < projectiles.size(); i++){
Projectile p = (Projectile) projectiles.get(i);
g.setColor(Color.BLACK);
g.fillRect(p.getX(), p.getY(), 5, 10);
}
g.drawImage(Battleship, ship.getCenterX() + 230, ship.getCenterY() -23, this);
g.drawImage(Bomb, b1.getCenterX() - 20, b1.getCenterY() - 20, this);
g.drawImage(Bomb, b2.getCenterX() - 20, b2.getCenterY() - 20, this);
g.setFont(font);
g.setColor(Color.BLACK);
g.drawString(Integer.toString(score), 710, 30);
}
#Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_LEFT:
ship.moveLeft();
break;
case KeyEvent.VK_RIGHT:
ship.moveRight();
break;
case KeyEvent.VK_CONTROL:
ship.shoot();
score = score +100;
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
ship.stop();
break;
case KeyEvent.VK_RIGHT:
ship.stop();
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public static Background getBg1() {
return bg1;
}
}
package kiloboltgame;
import java.util.ArrayList;
public class Ship {
//In Java, Class Variables should be private so that only its methods can change them.
private int centerX = 100;
private int centerY = 382;
private int speedX = 0;
private int speedY = 1;
private ArrayList<Projectile> projectiles = new ArrayList<Projectile>();
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0) {
System.out.println("Do not scroll the background.");
} else {
if (centerX <= 440) {
centerX += speedX;
} else {
System.out.println("Scroll Background Here");
}
}
// Updates Y Position
if (centerY + speedY >= 382) {
centerY = 382;
}else{
centerY += speedY;
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= -230) {
centerX = -229;
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void shoot(){
Projectile p = new Projectile(centerX + 285, centerY -10);
projectiles.add(p);
}
public ArrayList getProjectiles(){
return projectiles;
}
public void stop() {
speedX = 0;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
}
package kiloboltgame;
public class Background {
private int bgX, bgY, speedX;
public Background(int x, int y){
bgX = x;
bgY = y;
speedX = 0;
}
public void update() {
bgX += speedX;
if (bgX <= -800){
bgX += 1600;
}
}
public int getBgX() {
return bgX;
}
public int getBgY() {
return bgY;
}
public int getSpeedX() {
return speedX;
}
public void setBgX(int bgX) {
this.bgX = bgX;
}
public void setBgY(int bgY) {
this.bgY = bgY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
}
public class Projectile {
private int x, y, speedY;
private boolean visible;
public Projectile(int startX, int startY) {
x = startX;
y = startY;
speedY = -7;
visible = true;
}
public void update() {
y += speedY;
if(y > 480){
visible = false;
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getSpeedY() {
return speedY;
}
public boolean isVisible() {
return visible;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
}
package kiloboltgame;
public class Enemy {
private int maxHealth, currentHealth, power, speedX, centerX, centerY;
private Background bg = StartingClass.getBg1();
//Behavioral Methods
public void update(){
centerX += speedX;
speedX = bg.getSpeedX();
}
public void die(){
}
public void attack(){
}
public int getMaxHealth() {
return maxHealth;
}
public int getCurrentHealth() {
return currentHealth;
}
public int getPower() {
return power;
}
public int getSpeedX() {
return speedX;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public Background getBg() {
return bg;
}
public void setMaxHealth(int maxHealth) {
this.maxHealth = maxHealth;
}
public void setCurrentHealth(int currentHealth) {
this.currentHealth = currentHealth;
}
public void setPower(int power) {
this.power = power;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setBg(Background bg) {
this.bg = bg;
}
}
package kiloboltgame;
public class Bomb extends Enemy {
public Bomb(int centerX, int centerY) {
setCenterX(centerX);
setCenterY(centerY);
}
}
This is all code that i have so far (I know the background is f*ed since the game this is based on is scrolling right and i haven't fixed it yet.
I recommend putting all object creation in a seperate part of the program. I'd make a BombFactory with a makeBomb mathod that returns a new Bomb instance. Inside the factory, figure out the x-coordinate, for instance using a randomiser. As parameters, you could specify a y-coordinate and possibly an upper and lower bound for the x. This way you can make new Bombs on the fly.
public class BombFactory {
private final Random rand;
public BombFactory() {
this.rand = new Random();
}
public Bomb makeBomb(int lowerboundX, int rangeX, int yPos) {
final int xPos = lowerboundX + rand.nextInt(rangeX);
return new Bomb(xPos, yPos);
}
}
As for the behaviour, I'd look into inheritance and interfaces some more. I see a lot of methods occurring more than once. You generally want to avoid that kind of duplication. You can start by taking all the methods having something to do with coords or movement and putting them in an abstract base class.
You can make a method inside Enemy that checks for a collision and responds to that in different ways, depending on how the subclass overrides it. In case of a Bomb, it would probably always kill itself and whatever it came in contact with.
I want to make a 2D game for android. But I cannot make my object collide. I want to make the bear and the giraffe to collide when they interact, but it doesn't work.
This is the bear class:
package gamefoundation;
import java.awt.Rectangle;
public class Bear {
//In Java, Class Variables should be private so that only its methods can change them.
private int centerX = 50;
private int centerY = 430;
private int speedX = 0;
private int speedY = 0;
public static Rectangle rect = new Rectangle(0,0,0,0);
private boolean movingLeft = false;
private boolean movingRight = false;
private boolean movingUp = false;
private boolean movingDown = false;
private Giraffe giraffe;
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else {
if (centerX <= 763) /*batas maks kanan*/{
centerX += speedX;
}
}
if (speedY < 0) {
centerY += speedY;
} else {
if (centerY <= 430) /*batas maks bawah*/ {
centerY += speedY;
}
}
//biar beruangnya gak nembus sebelah kiri
if (centerX + speedX <= 60) {
centerX = 61;
}
//biar beruangnya gak nembus ke atas
if (centerY + speedY <= 60) {
centerY = 61;
}
//collision
rect.setRect(centerX-34, centerY-63, 68, 103);
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void moveUp() {
speedY = -6;
}
public void moveDown() {
speedY = 6;
}
public void stop() {
speedX = 0;
speedY = 0;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
public boolean isMovingLeft() {
return movingLeft;
}
public boolean isMovingRight() {
return movingRight;
}
public void setMovingLeft(boolean movingLeft) {
this.movingLeft = movingLeft;
}
public void setMovingRight(boolean movingRight) {
this.movingRight = movingRight;
}
public boolean isMovingUp() {
return movingUp;
}
public boolean isMovingDown() {
return movingDown;
}
public void setMovingUp(boolean movingUp) {
this.movingUp = movingUp;
}
public void setMovingDown(boolean movingDown) {
this.movingDown = movingDown;
}
}
The giraffe class:
package gamefoundation;
import java.awt.Rectangle;
public class Giraffe extends Animal {
private Rectangle r;
public Giraffe(int centerX, int centerY) {
setCenterX(centerX);
setCenterY(centerY);
r = new Rectangle();
}
public void checkVerticalCollision(Rectangle rbody){
if (rbody.intersects(r)){
System.out.println("collision w/ giraffe");
}
}
private void update() {
r.setBounds(getCenterX(), getCenterY(), 20, 20);
}
}
This is the StartingClass:
package gamefoundation;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
public class StartingClass extends Applet implements Runnable, KeyListener {
private Bear bear;
private Image image,beruang,map,burung,buaya,jerapah,monyet,rusa;
private Graphics second;
private URL base;
private static Map mp1,mp2;
private Bird bird;
private Crocodile crocodile;
private Deer deer;
private Giraffe giraffe;
private Monkey monkey;
#Override
public void init() {
setSize(800,480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Petualangan Bubu");
try{
base=getDocumentBase();
}catch(Exception e){
//TODO: handle exception
}
//image setups
beruang = getImage(base,"data/beruangsmall.png");
burung = getImage(base,"data/birdsmall.png");
buaya = getImage(base,"data/crocodilesmall.png");
rusa = getImage(base,"data/deersmall.png");
jerapah = getImage(base,"data/giraffesmall.png");
monyet = getImage(base,"data/monkeysmall.png");
map = getImage(base,"data/map.jpg");
}
#Override
public void start() {
mp1 = new Map(0,0);
bear = new Bear();
bird = new Bird(430,20);
crocodile = new Crocodile(410,120);
deer = new Deer(205,30);
giraffe = new Giraffe(580,86);
monkey = new Monkey(600,260);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
}
#Override
public void destroy() {
}
#Override
public void run() {
while(true) {
bear.update();
if(bear.getCenterX() == giraffe.getCenterX()) {
giraffe.checkVerticalCollision(bear.rect);
}
repaint();
try{
Thread.sleep(17);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
bear.moveUp();
bear.setMovingUp(true);
break;
case KeyEvent.VK_DOWN:
bear.moveDown();
bear.setMovingDown(true);
break;
case KeyEvent.VK_LEFT:
bear.moveLeft();
bear.setMovingLeft(true);
break;
case KeyEvent.VK_RIGHT:
bear.moveRight();
bear.setMovingRight(true);
break;
case KeyEvent.VK_SPACE:
System.out.println("Jump");
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
bear.stop();
break;
case KeyEvent.VK_DOWN:
bear.stop();
break;
case KeyEvent.VK_LEFT:
bear.stop();
break;
case KeyEvent.VK_RIGHT:
bear.stop();
break;
case KeyEvent.VK_SPACE:
System.out.println("Stop jumping");
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void update(Graphics g) {
if(image==null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(map, mp1.getMapX(), mp1.getMapY(), this);
g.drawImage(beruang, bear.getCenterX()-61, bear.getCenterY()-63, this);
g.drawImage(burung, bird.getCenterX(), bird.getCenterY(), this);
g.drawImage(buaya, crocodile.getCenterX(), crocodile.getCenterY(), this);
g.drawImage(rusa, deer.getCenterX(), deer.getCenterY(), this);
g.drawImage(jerapah, giraffe.getCenterX(), giraffe.getCenterY(), this);
g.drawImage(monyet, monkey.getCenterX(), monkey.getCenterY(), this);
g.drawRect((int)bear.rect.getX(), (int)bear.rect.getY(), (int)bear.rect.getWidth(), (int)bear.rect.getHeight());
}
}
As said in the comment your only checking for a collision when the CenterX of both the bear and giraffe are equal. I would suggest simply removing that if check it likely doesn't buy you anything performance wise.
Ok... So im creating my first 2d platform game... unfortunately everything is new but i have gotten everything else to work so far but I cant get collision to work. This is kinda long so i expect not to get an answer, but someone who can help... Thank you in advance.
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
public class Expordium {
private JFrame f = new JFrame("Expordium");
private boolean win;
private int level;
private Display display;
public boolean isR, isU, isL, isD;
public static void main(String[] args) {
Expordium game = new Expordium();
game.play(game);
}
Expordium(){
win=false;
level=1;
}
private void play(Expordium game){
display = new Display(game);
f.getContentPane().add(display);
f.addKeyListener(new MyKeyListener());
f.setSize(980 , 360);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
private void advanceLevel() {
level++;
}
public String getLevel() {
String strLevel;
strLevel=Integer.toString(level);
return strLevel;
}
public class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_UP:
isU=true;
break;
case KeyEvent.VK_DOWN:
isD=true;
break;
case KeyEvent.VK_LEFT:
isL=true;
break;
case KeyEvent.VK_RIGHT:
isR=true;
break;
case KeyEvent.VK_SPACE :
display.shoot();
}
}
public void keyReleased( KeyEvent e ) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_UP:
isU=false;
break;
case KeyEvent.VK_DOWN:
isD=false;
break;
case KeyEvent.VK_LEFT:
isL=false;
break;
case KeyEvent.VK_RIGHT:
isR=false;
break;
}
}
}
}
Display Class
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.HTMLDocument.Iterator;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
public class Display extends JPanel implements Runnable{
private static final int FPS = 1000 / 36;
private JFrame f = new JFrame("Expordium");
private Collection<Block> elements = new ArrayList<Block>();
private Collection<Bullet> bullets = new ArrayList<Bullet>();
private BufferedImage Bg;
public Wall wall;
public Guy guy;
public End end;
public Bullet bullet;
private String file;
private Expordium game;
private String[][] strLevel = new String[30][10];
private String[][] strWall = new String[30][10];
Display(Expordium g){
game=g;
readFile();
for(int i=0; i<30; i++){
for(int j=0; j<10; j++){
if(strLevel[i][j].equals("W")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-T.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("A")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-L.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("S")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-B.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("D")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-R.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("s")){
elements.add(guy=new Guy(i*32,j*32,false,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-R.PNG"));
}
if(strLevel[i][j].equals("e")){
elements.add(end=new End(i*32,j*32,false,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/End.PNG"));
}
}
}
new Thread(this).start();
}
public void run(){
long tm = System.currentTimeMillis();
while(true){
update();
repaint();
try {
tm += FPS;
Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
}
catch(InterruptedException e)
{
System.out.println(e);
}
}
}
This is the collision detection part:
public boolean collision() {
java.util.Iterator<Block> iterator = elements.iterator();
while(iterator.hasNext()){
if(iterator.next().isSolid && guy.isColliding((Block)iterator.next())){
return true;
}
}
return false;
}
End
public void update() {
if(!guy.isJump && game.isU){
guy.Jump();
}
if(game.isR){
if(!collision()){
guy.Move(2);
}
}
if(game.isL){
if(!collision()){
guy.Move(1);
}
}
if(guy.isJump){
guy.Jump();
}
}
public void paint(Graphics g){
try {
Bg = ImageIO.read(new File("C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/BackGround.PNG"));
} catch (IOException e) {}
g.drawImage(Bg, 0,0,null);
java.util.Iterator<Block> iterator = elements.iterator();
while(iterator.hasNext())
((Block) iterator.next()).draw(g);
java.util.Iterator<Bullet> iterator1 = bullets.iterator();
while(iterator1.hasNext())
((Block) iterator1.next()).draw(g);
}
private void readFile() {
int num=0;
String noFile = "";
String loc ="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Level/Level " + game.getLevel() + ".txt";
File Level = new File(loc);
file=TextFile.getContents(Level);
for(int i=0; i<file.length(); i++){
if(file.substring(num, num+1).equals("W") || file.substring(num, num+1).equals("A") || file.substring(num, num+1).equals("S") || file.substring(num, num+1).equals("D") || file.substring(num, num+1).equals("e") || file.substring(num, num+1).equals("s") || file.substring(num, num+1).equals(" ")){
noFile=noFile+file.substring(num, num+1);
}
num++;
}
num=0;
for(int j=0; j<10; j++){
for(int i=0; i<30; i++){
strLevel[i][j]=noFile.substring(num, num+1);
num++;
}
}
}
public void shoot() {
if(guy.dir==1){
bullets.add(new Bullet(guy.getX(),guy.getY(),1,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/Bullet.PNG"));
}
if(guy.dir==2){
bullets.add(new Bullet(guy.getX(),guy.getY(),2,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/Bullet.PNG"));
}
}
}
Guy Class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Guy extends Block{
private int x, y, groundY;
public boolean isSolid;
private BufferedImage guy;
public boolean isJump=false;
private int accM, accJ;
private String location;
public int dir=2;
public Guy(int startx, int starty, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
guy = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
isSolid=solid;
location=loc;
}
public boolean isColliding(Block e){
int leftSide = getX();
int rightSide = getX() + 31;
int top = getY();
int bottom = getY() + 31;
int eLeftSide = e.getX();
int eRightSide = e.getX() + 31;
int eTop = e.getY();
int eBottom = e.getY() + 31;
if(eLeftSide < rightSide)
if(eRightSide > leftSide)
if(eTop < bottom)
if(eBottom > top)
return true;
return false;
}
public void draw(Graphics g) {
try {
guy = ImageIO.read(new File(location));
} catch (IOException e) {}
g.drawImage(guy,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void setX(int x1){
x=x1;
}
public void setY(int y1){
y=y1;
}
public void Move(int i) {
if(i==2){
dir=2;
location="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-R.PNG";
x=x+2;
}
else{
dir=1;
location="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-L.PNG";
x=x-2;
}
}
public void Jump() {
if(groundY==0){
isJump=true;
y=y+3;
groundY=groundY+3;
}
else if(groundY!=0 && groundY<=48 && groundY!=96){
y=y-3;
groundY=groundY+3;
}
else if(groundY!=0 && groundY>=48 && groundY!=96){
y=y+3;
groundY=groundY+3;
}
else{
isJump=false;
groundY=0;
}
}
}
Wall Class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Wall extends Block{
private int x, y;
public boolean isSolid;
private BufferedImage wall;
public Wall(int startx, int starty, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
wall = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
isSolid=solid;
}
public void draw(Graphics g) {
g.drawImage(wall,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
End Class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class End extends Block{
private int x, y;
public boolean isSolid;
private BufferedImage end;
public End(int startx, int starty, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
end = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
isSolid=solid;
}
public void draw(Graphics g) {
g.drawImage(end,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
Block Class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public abstract class Block {
private int x, y;
public boolean isSolid;
private BufferedImage block;
private String location;
public Block(int startx, int starty, boolean solid, String loc) {
x=startx;
y=starty;
isSolid=solid;
location=loc;
try {
block = ImageIO.read(new File(loc));
} catch (IOException e) {
}
}
public abstract void draw(Graphics g);
public int getX(){
return x;
}
public int getY(){
return y;
}
}
Bullet Class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Bullet extends Block{
private int x, y;
public boolean isSolid;
private BufferedImage bullet;
public int dir;
public Bullet(int startx, int starty, int dir1, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
bullet = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
dir=dir1;
isSolid=solid;
}
public void draw(Graphics g) {
if(dir==1){
x=x-5;
}
if(dir==2){
x=x+5;
}
g.drawImage(bullet,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
This has nothing to do with your question, but what you are doing is so bad, especially my first remark.
Each time you render the game, you load the image for your "guy" from the file. You should load them all (player-left, player-right) and then render the correct image, depending on the direction of your "guy".
You are using absolute path to point to the images. Use relative paths.
Do not use 1 and 2 as directions, but something more logic, eg:
-2 means run to the left
-1 means no movement, but pointing to the left
(0 means no movement)
+1 means no movement, but pointing to the right
+2 means run to the right
Variable names do start with a lowercase character, eg: bg instead of Bg
Use in your next game project floats for the coordinates.
Here is some code:
private BufferedImage player_left;
private BufferedImage player_right;
public Guy() { // Your consturctor:
player_left = ImageIO.read(new File("resources/img/player-left.png"));
player_right = ImageIO.read(new Fiel("resources/img/player-right.png"));
}
public void draw(Graphics g)
{
if (direction == -1) { // left
g.draw(player_left, .......);
} else if (direction == 1) // right
{
g.draw(player_right, ......);
} else if (direction == ...)
{
.....
}
}
One thing I noticed is that you're calling the next() method twice in the iterator. Each time you call the next() method the iterator returns the next Block. If there are no Block objects left, you'll get an exception.
The code below fixes that, but I doubt if it's going to fix the problem itself...
public boolean collision() {
java.util.Iterator<Block> iterator = elements.iterator();
while(iterator.hasNext()){
Block item = iterator.next();
if(item.isSolid && guy.isColliding(item)){
return true;
}
}
return false;
}
Have you ever looked into an open source 2d game engine ? It will do all the heavy lifting for you e.g. Physics / Collision Detection / Controls.
Here is a usefull stackoverflow post:
https://stackoverflow.com/questions/293079/java-2d-game-frameworks
in the following part of the code:
if(eLeftSide < rightSide)
if(eRightSide > leftSide)
if(eTop < bottom)
if(eBottom > top)
return true;
return false;
you only check for one instance of collision (when the guy is inside the block). For simple bounding box collisions you'll need other type of checking. Try drawing two boxes on paper and check how they can be colliding and try to implement that